diff options
| author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:43:28 +0300 | 
|---|---|---|
| committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-04-29 07:56:09 +0300 | 
| commit | 1b68f71348ecf3983b76b40d7940da8377f049b7 (patch) | |
| tree | 2974eddaef130a067c26033d60a59fc790365b3d /indra/media_plugins/gstreamer010 | |
| parent | af4ea94efc1999f3b19fd8d643d0331f0b77e265 (diff) | |
#824 Process source files in bulk: replace tabs with spaces, convert CRLF to LF, and trim trailing whitespaces as needed
Diffstat (limited to 'indra/media_plugins/gstreamer010')
7 files changed, 1480 insertions, 1480 deletions
| diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h index 6bc272c009..cae11a5cb3 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llmediaimplgstreamer.h   * @author Tofu Linden   * @brief implementation that supports media playback via GStreamer. @@ -7,21 +7,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -44,8 +44,8 @@ extern "C" {  extern "C" {  gboolean llmediaimplgstreamer_bus_callback (GstBus     *bus, -					    GstMessage *message, -					    gpointer    data); +                        GstMessage *message, +                        gpointer    data);  }  #endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp index 2e4baaa9eb..dcc04b37e4 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file llmediaimplgstreamer_syms.cpp   * @brief dynamic GStreamer symbol-grabbing code   * @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -48,8 +48,8 @@ extern "C" {  GstDebugCategory*  ll_gst_debug_category_new(gchar *name, guint color, gchar *description)  { -	static GstDebugCategory dummy; -	return &dummy; +    static GstDebugCategory dummy; +    return &dummy;  }  void ll_gst_debug_register_funcptr(GstDebugFuncPtr func, gchar* ptrname)  { @@ -62,105 +62,105 @@ static apr_dso_handle_t *sSymGSTDSOHandleV = NULL;  bool grab_gst_syms(std::string gst_dso_name, -		   std::string gst_dso_name_vid) +           std::string gst_dso_name_vid)  { -	if (sSymsGrabbed) -	{ -		// already have grabbed good syms -		return TRUE; -	} +    if (sSymsGrabbed) +    { +        // already have grabbed good syms +        return TRUE; +    } -	bool sym_error = false; -	bool rtn = false; -	apr_status_t rv; -	apr_dso_handle_t *sSymGSTDSOHandle = NULL; +    bool sym_error = false; +    bool rtn = false; +    apr_status_t rv; +    apr_dso_handle_t *sSymGSTDSOHandle = NULL;  #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) -	//attempt to load the shared libraries -	apr_pool_create(&sSymGSTDSOMemoryPool, NULL); -   -	if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, -					       gst_dso_name.c_str(), -					       sSymGSTDSOMemoryPool) )) -	{ -		INFOMSG("Found DSO: %s", gst_dso_name.c_str()); +    //attempt to load the shared libraries +    apr_pool_create(&sSymGSTDSOMemoryPool, NULL); + +    if ( APR_SUCCESS == (rv = apr_dso_load(&sSymGSTDSOHandle, +                           gst_dso_name.c_str(), +                           sSymGSTDSOMemoryPool) )) +    { +        INFOMSG("Found DSO: %s", gst_dso_name.c_str());  #include "llmediaimplgstreamer_syms_raw.inc" -       -		if ( sSymGSTDSOHandle ) -		{ -			sSymGSTDSOHandleG = sSymGSTDSOHandle; -			sSymGSTDSOHandle = NULL; -		} -       -		if ( APR_SUCCESS == -		     (rv = apr_dso_load(&sSymGSTDSOHandle, -					gst_dso_name_vid.c_str(), -					sSymGSTDSOMemoryPool) )) -		{ -			INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str()); + +        if ( sSymGSTDSOHandle ) +        { +            sSymGSTDSOHandleG = sSymGSTDSOHandle; +            sSymGSTDSOHandle = NULL; +        } + +        if ( APR_SUCCESS == +             (rv = apr_dso_load(&sSymGSTDSOHandle, +                    gst_dso_name_vid.c_str(), +                    sSymGSTDSOMemoryPool) )) +        { +            INFOMSG("Found DSO: %s", gst_dso_name_vid.c_str());  #include "llmediaimplgstreamer_syms_rawv.inc" -			rtn = !sym_error; -		} -		else -		{ -			INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); -			rtn = false; // failure -		} -	} -	else -	{ -		INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); -		rtn = false; // failure -	} - -	if (sym_error) -	{ -		WARNMSG("Failed to find necessary symbols in GStreamer libraries."); -	} -	 -	if ( sSymGSTDSOHandle ) -	{ -		sSymGSTDSOHandleV = sSymGSTDSOHandle; -		sSymGSTDSOHandle = NULL; -	} +            rtn = !sym_error; +        } +        else +        { +            INFOMSG("Couldn't load DSO: %s", gst_dso_name_vid.c_str()); +            rtn = false; // failure +        } +    } +    else +    { +        INFOMSG("Couldn't load DSO: %s", gst_dso_name.c_str()); +        rtn = false; // failure +    } + +    if (sym_error) +    { +        WARNMSG("Failed to find necessary symbols in GStreamer libraries."); +    } + +    if ( sSymGSTDSOHandle ) +    { +        sSymGSTDSOHandleV = sSymGSTDSOHandle; +        sSymGSTDSOHandle = NULL; +    }  #undef LL_GST_SYM -	sSymsGrabbed = !!rtn; -	return rtn; +    sSymsGrabbed = !!rtn; +    return rtn;  }  void ungrab_gst_syms() -{  -	// should be safe to call regardless of whether we've -	// actually grabbed syms. - -	if ( sSymGSTDSOHandleG ) -	{ -		apr_dso_unload(sSymGSTDSOHandleG); -		sSymGSTDSOHandleG = NULL; -	} -	 -	if ( sSymGSTDSOHandleV ) -	{ -		apr_dso_unload(sSymGSTDSOHandleV); -		sSymGSTDSOHandleV = NULL; -	} -	 -	if ( sSymGSTDSOMemoryPool ) -	{ -		apr_pool_destroy(sSymGSTDSOMemoryPool); -		sSymGSTDSOMemoryPool = NULL; -	} -	 -	// NULL-out all of the symbols we'd grabbed +{ +    // should be safe to call regardless of whether we've +    // actually grabbed syms. + +    if ( sSymGSTDSOHandleG ) +    { +        apr_dso_unload(sSymGSTDSOHandleG); +        sSymGSTDSOHandleG = NULL; +    } + +    if ( sSymGSTDSOHandleV ) +    { +        apr_dso_unload(sSymGSTDSOHandleV); +        sSymGSTDSOHandleV = NULL; +    } + +    if ( sSymGSTDSOMemoryPool ) +    { +        apr_pool_destroy(sSymGSTDSOMemoryPool); +        sSymGSTDSOMemoryPool = NULL; +    } + +    // NULL-out all of the symbols we'd grabbed  #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) do{ll##GSTSYM = NULL;}while(0)  #include "llmediaimplgstreamer_syms_raw.inc"  #include "llmediaimplgstreamer_syms_rawv.inc"  #undef LL_GST_SYM -	sSymsGrabbed = false; +    sSymsGrabbed = false;  } diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h index d1559089c8..57d446c7df 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamer_syms.h @@ -1,4 +1,4 @@ -/**  +/**   * @file llmediaimplgstreamer_syms.h   * @brief dynamic GStreamer symbol-grabbing code   * @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -35,7 +35,7 @@ extern "C" {  }  bool grab_gst_syms(std::string gst_dso_name, -		   std::string gst_dso_name_vid); +           std::string gst_dso_name_vid);  void ungrab_gst_syms();  #define LL_GST_SYM(REQ, GSTSYM, RTN, ...) extern RTN (*ll##GSTSYM)(__VA_ARGS__) diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h index e7b31bec94..43ebad6744 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamertriviallogging.h @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2009&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp index 932aaffa1b..acec0f2399 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -58,139 +58,139 @@ GST_BOILERPLATE (GstSLVideo, gst_slvideo, GstVideoSink,      GST_TYPE_VIDEO_SINK);  static void gst_slvideo_set_property (GObject * object, guint prop_id, -				      const GValue * value, -				      GParamSpec * pspec); +                      const GValue * value, +                      GParamSpec * pspec);  static void gst_slvideo_get_property (GObject * object, guint prop_id, -				      GValue * value, GParamSpec * pspec); +                      GValue * value, GParamSpec * pspec);  static void  gst_slvideo_base_init (gpointer gclass)  { -	static GstElementDetails element_details = { -		(gchar*)"PluginTemplate", -		(gchar*)"Generic/PluginTemplate", -		(gchar*)"Generic Template Element", -		(gchar*)"Linden Lab" -	}; -	GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); -	 -	llgst_element_class_add_pad_template (element_class, -			      llgst_static_pad_template_get (&sink_factory)); -	llgst_element_class_set_details (element_class, &element_details); +    static GstElementDetails element_details = { +        (gchar*)"PluginTemplate", +        (gchar*)"Generic/PluginTemplate", +        (gchar*)"Generic Template Element", +        (gchar*)"Linden Lab" +    }; +    GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); + +    llgst_element_class_add_pad_template (element_class, +                  llgst_static_pad_template_get (&sink_factory)); +    llgst_element_class_set_details (element_class, &element_details);  }  static void  gst_slvideo_finalize (GObject * object)  { -	GstSLVideo *slvideo; -	slvideo = GST_SLVIDEO (object); -	if (slvideo->caps) -	{ -		llgst_caps_unref(slvideo->caps); -	} - -	G_OBJECT_CLASS(parent_class)->finalize (object); +    GstSLVideo *slvideo; +    slvideo = GST_SLVIDEO (object); +    if (slvideo->caps) +    { +        llgst_caps_unref(slvideo->caps); +    } + +    G_OBJECT_CLASS(parent_class)->finalize (object);  }  static GstFlowReturn  gst_slvideo_show_frame (GstBaseSink * bsink, GstBuffer * buf)  { -	GstSLVideo *slvideo; -	llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); -	 -	slvideo = GST_SLVIDEO(bsink); -	 -	DEBUGMSG("transferring a frame of %dx%d <- %p (%d)", -		 slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), -		 slvideo->format); - -	if (GST_BUFFER_DATA(buf)) -	{ -		// copy frame and frame info into neutral territory -		GST_OBJECT_LOCK(slvideo); -		slvideo->retained_frame_ready = TRUE; -		slvideo->retained_frame_width = slvideo->width; -		slvideo->retained_frame_height = slvideo->height; -		slvideo->retained_frame_format = slvideo->format; -		int rowbytes =  -			SLVPixelFormatBytes[slvideo->retained_frame_format] * -			slvideo->retained_frame_width; -		int needbytes = rowbytes * slvideo->retained_frame_width; -		// resize retained frame hunk only if necessary -		if (needbytes != slvideo->retained_frame_allocbytes) -		{ -			delete[] slvideo->retained_frame_data; -			slvideo->retained_frame_data = new unsigned char[needbytes]; -			slvideo->retained_frame_allocbytes = needbytes; -			 -		} -		// copy the actual frame data to neutral territory - -		// flipped, for GL reasons -		for (int ypos=0; ypos<slvideo->height; ++ypos) -		{ -			memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes], -			       &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]), -			       rowbytes); -		} -		// done with the shared data -		GST_OBJECT_UNLOCK(slvideo); -	} - -	return GST_FLOW_OK; +    GstSLVideo *slvideo; +    llg_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); + +    slvideo = GST_SLVIDEO(bsink); + +    DEBUGMSG("transferring a frame of %dx%d <- %p (%d)", +         slvideo->width, slvideo->height, GST_BUFFER_DATA(buf), +         slvideo->format); + +    if (GST_BUFFER_DATA(buf)) +    { +        // copy frame and frame info into neutral territory +        GST_OBJECT_LOCK(slvideo); +        slvideo->retained_frame_ready = TRUE; +        slvideo->retained_frame_width = slvideo->width; +        slvideo->retained_frame_height = slvideo->height; +        slvideo->retained_frame_format = slvideo->format; +        int rowbytes = +            SLVPixelFormatBytes[slvideo->retained_frame_format] * +            slvideo->retained_frame_width; +        int needbytes = rowbytes * slvideo->retained_frame_width; +        // resize retained frame hunk only if necessary +        if (needbytes != slvideo->retained_frame_allocbytes) +        { +            delete[] slvideo->retained_frame_data; +            slvideo->retained_frame_data = new unsigned char[needbytes]; +            slvideo->retained_frame_allocbytes = needbytes; + +        } +        // copy the actual frame data to neutral territory - +        // flipped, for GL reasons +        for (int ypos=0; ypos<slvideo->height; ++ypos) +        { +            memcpy(&slvideo->retained_frame_data[(slvideo->height-1-ypos)*rowbytes], +                   &(((unsigned char*)GST_BUFFER_DATA(buf))[ypos*rowbytes]), +                   rowbytes); +        } +        // done with the shared data +        GST_OBJECT_UNLOCK(slvideo); +    } + +    return GST_FLOW_OK;  }  static GstStateChangeReturn  gst_slvideo_change_state(GstElement * element, GstStateChange transition)  { -	GstSLVideo *slvideo; -	GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; -	 -	slvideo = GST_SLVIDEO (element); - -	switch (transition) { -	case GST_STATE_CHANGE_NULL_TO_READY: -		break; -	case GST_STATE_CHANGE_READY_TO_PAUSED: -		break; -	case GST_STATE_CHANGE_PAUSED_TO_PLAYING: -		break; -	default: -		break; -	} - -	ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); -	if (ret == GST_STATE_CHANGE_FAILURE) -		return ret; - -	switch (transition) { -	case GST_STATE_CHANGE_PLAYING_TO_PAUSED: -		break; -	case GST_STATE_CHANGE_PAUSED_TO_READY: -		slvideo->fps_n = 0; -		slvideo->fps_d = 1; -		GST_VIDEO_SINK_WIDTH(slvideo) = 0; -		GST_VIDEO_SINK_HEIGHT(slvideo) = 0; -		break; -	case GST_STATE_CHANGE_READY_TO_NULL: -		break; -	default: -		break; -	} - -	return ret; +    GstSLVideo *slvideo; +    GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + +    slvideo = GST_SLVIDEO (element); + +    switch (transition) { +    case GST_STATE_CHANGE_NULL_TO_READY: +        break; +    case GST_STATE_CHANGE_READY_TO_PAUSED: +        break; +    case GST_STATE_CHANGE_PAUSED_TO_PLAYING: +        break; +    default: +        break; +    } + +    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); +    if (ret == GST_STATE_CHANGE_FAILURE) +        return ret; + +    switch (transition) { +    case GST_STATE_CHANGE_PLAYING_TO_PAUSED: +        break; +    case GST_STATE_CHANGE_PAUSED_TO_READY: +        slvideo->fps_n = 0; +        slvideo->fps_d = 1; +        GST_VIDEO_SINK_WIDTH(slvideo) = 0; +        GST_VIDEO_SINK_HEIGHT(slvideo) = 0; +        break; +    case GST_STATE_CHANGE_READY_TO_NULL: +        break; +    default: +        break; +    } + +    return ret;  }  static GstCaps *  gst_slvideo_get_caps (GstBaseSink * bsink)  { -	GstSLVideo *slvideo; -	slvideo = GST_SLVIDEO(bsink); -	 -	return llgst_caps_ref (slvideo->caps); +    GstSLVideo *slvideo; +    slvideo = GST_SLVIDEO(bsink); + +    return llgst_caps_ref (slvideo->caps);  } @@ -198,199 +198,199 @@ gst_slvideo_get_caps (GstBaseSink * bsink)  static gboolean  gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)  { -	GstSLVideo *filter; -	GstStructure *structure; -	 -	GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); -	 -	filter = GST_SLVIDEO(bsink); - -	int width, height; -	gboolean ret; -	const GValue *fps; -	const GValue *par; -	structure = llgst_caps_get_structure (caps, 0); -	ret = llgst_structure_get_int (structure, "width", &width); -	ret = ret && llgst_structure_get_int (structure, "height", &height); -	fps = llgst_structure_get_value (structure, "framerate"); -	ret = ret && (fps != NULL); -	par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); -	if (!ret) -		return FALSE; - -	INFOMSG("** filter caps set with width=%d, height=%d", width, height); - -	GST_OBJECT_LOCK(filter); - -	filter->width = width; -	filter->height = height; - -	filter->fps_n = llgst_value_get_fraction_numerator(fps); -	filter->fps_d = llgst_value_get_fraction_denominator(fps); -	if (par) -	{ -		filter->par_n = llgst_value_get_fraction_numerator(par); -		filter->par_d = llgst_value_get_fraction_denominator(par); -	} -	else -	{ -		filter->par_n = 1; -		filter->par_d = 1; -	} -	GST_VIDEO_SINK_WIDTH(filter) = width; -	GST_VIDEO_SINK_HEIGHT(filter) = height; -	 -	// crufty lump - we *always* accept *only* RGBX now. -	/* -	filter->format = SLV_PF_UNKNOWN; -	if (0 == strcmp(llgst_structure_get_name(structure), -			"video/x-raw-rgb")) -	{ -		int red_mask; -		int green_mask; -		int blue_mask; -		llgst_structure_get_int(structure, "red_mask", &red_mask); -		llgst_structure_get_int(structure, "green_mask", &green_mask); -		llgst_structure_get_int(structure, "blue_mask", &blue_mask); -		if ((unsigned int)red_mask   == 0xFF000000 && -		    (unsigned int)green_mask == 0x00FF0000 && -		    (unsigned int)blue_mask  == 0x0000FF00) -		{ -			filter->format = SLV_PF_RGBX; -			//fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n"); -		} else if ((unsigned int)red_mask   == 0x0000FF00 && -			   (unsigned int)green_mask == 0x00FF0000 && -			   (unsigned int)blue_mask  == 0xFF000000) -		{ -			filter->format = SLV_PF_BGRX; -			//fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); -		} -		}*/ -	 -	filter->format = SLV_PF_RGBX; - -	GST_OBJECT_UNLOCK(filter); - -	return TRUE; +    GstSLVideo *filter; +    GstStructure *structure; + +    GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); + +    filter = GST_SLVIDEO(bsink); + +    int width, height; +    gboolean ret; +    const GValue *fps; +    const GValue *par; +    structure = llgst_caps_get_structure (caps, 0); +    ret = llgst_structure_get_int (structure, "width", &width); +    ret = ret && llgst_structure_get_int (structure, "height", &height); +    fps = llgst_structure_get_value (structure, "framerate"); +    ret = ret && (fps != NULL); +    par = llgst_structure_get_value (structure, "pixel-aspect-ratio"); +    if (!ret) +        return FALSE; + +    INFOMSG("** filter caps set with width=%d, height=%d", width, height); + +    GST_OBJECT_LOCK(filter); + +    filter->width = width; +    filter->height = height; + +    filter->fps_n = llgst_value_get_fraction_numerator(fps); +    filter->fps_d = llgst_value_get_fraction_denominator(fps); +    if (par) +    { +        filter->par_n = llgst_value_get_fraction_numerator(par); +        filter->par_d = llgst_value_get_fraction_denominator(par); +    } +    else +    { +        filter->par_n = 1; +        filter->par_d = 1; +    } +    GST_VIDEO_SINK_WIDTH(filter) = width; +    GST_VIDEO_SINK_HEIGHT(filter) = height; + +    // crufty lump - we *always* accept *only* RGBX now. +    /* +    filter->format = SLV_PF_UNKNOWN; +    if (0 == strcmp(llgst_structure_get_name(structure), +            "video/x-raw-rgb")) +    { +        int red_mask; +        int green_mask; +        int blue_mask; +        llgst_structure_get_int(structure, "red_mask", &red_mask); +        llgst_structure_get_int(structure, "green_mask", &green_mask); +        llgst_structure_get_int(structure, "blue_mask", &blue_mask); +        if ((unsigned int)red_mask   == 0xFF000000 && +            (unsigned int)green_mask == 0x00FF0000 && +            (unsigned int)blue_mask  == 0x0000FF00) +        { +            filter->format = SLV_PF_RGBX; +            //fprintf(stderr, "\n\nPIXEL FORMAT RGB\n\n"); +        } else if ((unsigned int)red_mask   == 0x0000FF00 && +               (unsigned int)green_mask == 0x00FF0000 && +               (unsigned int)blue_mask  == 0xFF000000) +        { +            filter->format = SLV_PF_BGRX; +            //fprintf(stderr, "\n\nPIXEL FORMAT BGR\n\n"); +        } +        }*/ + +    filter->format = SLV_PF_RGBX; + +    GST_OBJECT_UNLOCK(filter); + +    return TRUE;  }  static gboolean  gst_slvideo_start (GstBaseSink * bsink)  { -	gboolean ret = TRUE; -	 -	GST_SLVIDEO(bsink); +    gboolean ret = TRUE; + +    GST_SLVIDEO(bsink); -	return ret; +    return ret;  }  static gboolean  gst_slvideo_stop (GstBaseSink * bsink)  { -	GstSLVideo *slvideo; -	slvideo = GST_SLVIDEO(bsink); - -	// free-up retained frame buffer -	GST_OBJECT_LOCK(slvideo); -	slvideo->retained_frame_ready = FALSE; -	delete[] slvideo->retained_frame_data; -	slvideo->retained_frame_data = NULL; -	slvideo->retained_frame_allocbytes = 0; -	GST_OBJECT_UNLOCK(slvideo); - -	return TRUE; +    GstSLVideo *slvideo; +    slvideo = GST_SLVIDEO(bsink); + +    // free-up retained frame buffer +    GST_OBJECT_LOCK(slvideo); +    slvideo->retained_frame_ready = FALSE; +    delete[] slvideo->retained_frame_data; +    slvideo->retained_frame_data = NULL; +    slvideo->retained_frame_allocbytes = 0; +    GST_OBJECT_UNLOCK(slvideo); + +    return TRUE;  }  static GstFlowReturn  gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, -			  GstCaps * caps, GstBuffer ** buf) +              GstCaps * caps, GstBuffer ** buf)  { -	gint width, height; -	GstStructure *structure = NULL; -	GstSLVideo *slvideo; -	slvideo = GST_SLVIDEO(bsink); - -	// caps == requested caps -	// we can ignore these and reverse-negotiate our preferred dimensions with -	// the peer if we like - we need to do this to obey dynamic resize requests -	// flowing in from the app. -	structure = llgst_caps_get_structure (caps, 0); -	if (!llgst_structure_get_int(structure, "width", &width) || -	    !llgst_structure_get_int(structure, "height", &height)) -	{ -		GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); -		return GST_FLOW_NOT_NEGOTIATED; -	} - -	GstBuffer *newbuf = llgst_buffer_new(); -	bool made_bufferdata_ptr = false; +    gint width, height; +    GstStructure *structure = NULL; +    GstSLVideo *slvideo; +    slvideo = GST_SLVIDEO(bsink); + +    // caps == requested caps +    // we can ignore these and reverse-negotiate our preferred dimensions with +    // the peer if we like - we need to do this to obey dynamic resize requests +    // flowing in from the app. +    structure = llgst_caps_get_structure (caps, 0); +    if (!llgst_structure_get_int(structure, "width", &width) || +        !llgst_structure_get_int(structure, "height", &height)) +    { +        GST_WARNING_OBJECT (slvideo, "no width/height in caps %" GST_PTR_FORMAT, caps); +        return GST_FLOW_NOT_NEGOTIATED; +    } + +    GstBuffer *newbuf = llgst_buffer_new(); +    bool made_bufferdata_ptr = false;  #define MAXDEPTHHACK 4 -	 -	GST_OBJECT_LOCK(slvideo); -	if (slvideo->resize_forced_always) // app is giving us a fixed size to work with -	{ -		gint slwantwidth, slwantheight; -		slwantwidth = slvideo->resize_try_width; -		slwantheight = slvideo->resize_try_height; -	 -		if (slwantwidth != width || -		    slwantheight != height) -		{ -			// don't like requested caps, we will issue our own suggestion - copy -			// the requested caps but substitute our own width and height and see -			// if our peer is happy with that. -		 -			GstCaps *desired_caps; -			GstStructure *desired_struct; -			desired_caps = llgst_caps_copy (caps); -			desired_struct = llgst_caps_get_structure (desired_caps, 0); -			 -			GValue value = {0}; -			g_value_init(&value, G_TYPE_INT); -			g_value_set_int(&value, slwantwidth); -			llgst_structure_set_value (desired_struct, "width", &value); -			g_value_unset(&value); -			g_value_init(&value, G_TYPE_INT); -			g_value_set_int(&value, slwantheight); -			llgst_structure_set_value (desired_struct, "height", &value); -			 -			if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), -							desired_caps)) -			{ -				// todo: re-use buffers from a pool? -				// todo: set MALLOCDATA to null, set DATA to point straight to shm? -				 -				// peer likes our cap suggestion -				DEBUGMSG("peer loves us :)"); -				GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; -				GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); -				GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); -				llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); - -				made_bufferdata_ptr = true; -			} else { -				// peer hates our cap suggestion -				INFOMSG("peer hates us :("); -				llgst_caps_unref(desired_caps); -			} -		} -	} - -	GST_OBJECT_UNLOCK(slvideo); - -	if (!made_bufferdata_ptr) // need to fallback to malloc at original size -	{ -		GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; -		GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); -		GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); -		llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); -	} - -	*buf = GST_BUFFER_CAST(newbuf); - -	return GST_FLOW_OK; + +    GST_OBJECT_LOCK(slvideo); +    if (slvideo->resize_forced_always) // app is giving us a fixed size to work with +    { +        gint slwantwidth, slwantheight; +        slwantwidth = slvideo->resize_try_width; +        slwantheight = slvideo->resize_try_height; + +        if (slwantwidth != width || +            slwantheight != height) +        { +            // don't like requested caps, we will issue our own suggestion - copy +            // the requested caps but substitute our own width and height and see +            // if our peer is happy with that. + +            GstCaps *desired_caps; +            GstStructure *desired_struct; +            desired_caps = llgst_caps_copy (caps); +            desired_struct = llgst_caps_get_structure (desired_caps, 0); + +            GValue value = {0}; +            g_value_init(&value, G_TYPE_INT); +            g_value_set_int(&value, slwantwidth); +            llgst_structure_set_value (desired_struct, "width", &value); +            g_value_unset(&value); +            g_value_init(&value, G_TYPE_INT); +            g_value_set_int(&value, slwantheight); +            llgst_structure_set_value (desired_struct, "height", &value); + +            if (llgst_pad_peer_accept_caps (GST_VIDEO_SINK_PAD (slvideo), +                            desired_caps)) +            { +                // todo: re-use buffers from a pool? +                // todo: set MALLOCDATA to null, set DATA to point straight to shm? + +                // peer likes our cap suggestion +                DEBUGMSG("peer loves us :)"); +                GST_BUFFER_SIZE(newbuf) = slwantwidth * slwantheight * MAXDEPTHHACK; +                GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); +                GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); +                llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), desired_caps); + +                made_bufferdata_ptr = true; +            } else { +                // peer hates our cap suggestion +                INFOMSG("peer hates us :("); +                llgst_caps_unref(desired_caps); +            } +        } +    } + +    GST_OBJECT_UNLOCK(slvideo); + +    if (!made_bufferdata_ptr) // need to fallback to malloc at original size +    { +        GST_BUFFER_SIZE(newbuf) = width * height * MAXDEPTHHACK; +        GST_BUFFER_MALLOCDATA(newbuf) = (guint8*)g_malloc(GST_BUFFER_SIZE(newbuf)); +        GST_BUFFER_DATA(newbuf) = GST_BUFFER_MALLOCDATA(newbuf); +        llgst_buffer_set_caps (GST_BUFFER_CAST(newbuf), caps); +    } + +    *buf = GST_BUFFER_CAST(newbuf); + +    return GST_FLOW_OK;  } @@ -398,32 +398,32 @@ gst_slvideo_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,  static void  gst_slvideo_class_init (GstSLVideoClass * klass)  { -	GObjectClass *gobject_class; -	GstElementClass *gstelement_class; -	GstBaseSinkClass *gstbasesink_class; -	 -	gobject_class = (GObjectClass *) klass; -	gstelement_class = (GstElementClass *) klass; -	gstbasesink_class = (GstBaseSinkClass *) klass; -	 -	gobject_class->finalize = gst_slvideo_finalize; -	gobject_class->set_property = gst_slvideo_set_property; -	gobject_class->get_property = gst_slvideo_get_property; -	 -	gstelement_class->change_state = gst_slvideo_change_state; -	 +    GObjectClass *gobject_class; +    GstElementClass *gstelement_class; +    GstBaseSinkClass *gstbasesink_class; + +    gobject_class = (GObjectClass *) klass; +    gstelement_class = (GstElementClass *) klass; +    gstbasesink_class = (GstBaseSinkClass *) klass; + +    gobject_class->finalize = gst_slvideo_finalize; +    gobject_class->set_property = gst_slvideo_set_property; +    gobject_class->get_property = gst_slvideo_get_property; + +    gstelement_class->change_state = gst_slvideo_change_state; +  #define LLGST_DEBUG_FUNCPTR(p) (p) -	gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps); -	gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps); -	gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc); -	//gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times); -	gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); -	gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); -	 -	gstbasesink_class->start = LLGST_DEBUG_FUNCPTR (gst_slvideo_start); -	gstbasesink_class->stop = LLGST_DEBUG_FUNCPTR (gst_slvideo_stop); -	 -	//	gstbasesink_class->unlock = LLGST_DEBUG_FUNCPTR (gst_slvideo_unlock); +    gstbasesink_class->get_caps = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_caps); +    gstbasesink_class->set_caps = LLGST_DEBUG_FUNCPTR( gst_slvideo_set_caps); +    gstbasesink_class->buffer_alloc=LLGST_DEBUG_FUNCPTR(gst_slvideo_buffer_alloc); +    //gstbasesink_class->get_times = LLGST_DEBUG_FUNCPTR (gst_slvideo_get_times); +    gstbasesink_class->preroll = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); +    gstbasesink_class->render = LLGST_DEBUG_FUNCPTR (gst_slvideo_show_frame); + +    gstbasesink_class->start = LLGST_DEBUG_FUNCPTR (gst_slvideo_start); +    gstbasesink_class->stop = LLGST_DEBUG_FUNCPTR (gst_slvideo_stop); + +    //  gstbasesink_class->unlock = LLGST_DEBUG_FUNCPTR (gst_slvideo_unlock);  #undef LLGST_DEBUG_FUNCPTR  } @@ -435,52 +435,52 @@ gst_slvideo_class_init (GstSLVideoClass * klass)   */  static void  gst_slvideo_init (GstSLVideo * filter, -		  GstSLVideoClass * gclass) +          GstSLVideoClass * gclass)  { -	filter->caps = NULL; -	filter->width = -1; -	filter->height = -1; - -	// this is the info we share with the client app -	GST_OBJECT_LOCK(filter); -	filter->retained_frame_ready = FALSE; -	filter->retained_frame_data = NULL; -	filter->retained_frame_allocbytes = 0; -	filter->retained_frame_width = filter->width; -	filter->retained_frame_height = filter->height; -	filter->retained_frame_format = SLV_PF_UNKNOWN; -	GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); -	llgst_caps_replace (&filter->caps, caps); -	filter->resize_forced_always = false; -	filter->resize_try_width = -1; -	filter->resize_try_height = -1; -	GST_OBJECT_UNLOCK(filter); +    filter->caps = NULL; +    filter->width = -1; +    filter->height = -1; + +    // this is the info we share with the client app +    GST_OBJECT_LOCK(filter); +    filter->retained_frame_ready = FALSE; +    filter->retained_frame_data = NULL; +    filter->retained_frame_allocbytes = 0; +    filter->retained_frame_width = filter->width; +    filter->retained_frame_height = filter->height; +    filter->retained_frame_format = SLV_PF_UNKNOWN; +    GstCaps *caps = llgst_caps_from_string (SLV_ALLCAPS); +    llgst_caps_replace (&filter->caps, caps); +    filter->resize_forced_always = false; +    filter->resize_try_width = -1; +    filter->resize_try_height = -1; +    GST_OBJECT_UNLOCK(filter);  }  static void  gst_slvideo_set_property (GObject * object, guint prop_id, -			  const GValue * value, GParamSpec * pspec) +              const GValue * value, GParamSpec * pspec)  { -	llg_return_if_fail (GST_IS_SLVIDEO (object)); -	 -	switch (prop_id) { -	default: -		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -		break; -	} +    llg_return_if_fail (GST_IS_SLVIDEO (object)); + +    switch (prop_id) { +    default: +        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +        break; +    }  }  static void  gst_slvideo_get_property (GObject * object, guint prop_id, -			  GValue * value, GParamSpec * pspec) +              GValue * value, GParamSpec * pspec)  { -	llg_return_if_fail (GST_IS_SLVIDEO (object)); +    llg_return_if_fail (GST_IS_SLVIDEO (object)); -	switch (prop_id) { -	default: -		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -		break; -	} +    switch (prop_id) { +    default: +        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +        break; +    }  } @@ -492,13 +492,13 @@ gst_slvideo_get_property (GObject * object, guint prop_id,  static gboolean  plugin_init (GstPlugin * plugin)  { -	DEBUGMSG("PLUGIN INIT"); +    DEBUGMSG("PLUGIN INIT"); -	GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", -				 0, (gchar*)"Second Life Video Sink"); +    GST_DEBUG_CATEGORY_INIT (gst_slvideo_debug, (gchar*)"private-slvideo-plugin", +                 0, (gchar*)"Second Life Video Sink"); -	return llgst_element_register (plugin, "private-slvideo", -				       GST_RANK_NONE, GST_TYPE_SLVIDEO); +    return llgst_element_register (plugin, "private-slvideo", +                       GST_RANK_NONE, GST_TYPE_SLVIDEO);  }  /* this is the structure that gstreamer looks for to register plugins @@ -510,17 +510,17 @@ plugin_init (GstPlugin * plugin)  #define PACKAGE (gchar*)"packagehack"  // this macro quietly refers to PACKAGE internally  GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, -		   GST_VERSION_MINOR, -		   (gchar*)"private-slvideoplugin",  -		   (gchar*)"SL Video sink plugin", -		   plugin_init, (gchar*)"1.0", (gchar*)"LGPL", -		   (gchar*)"Second Life", -		   (gchar*)"http://www.secondlife.com/"); +           GST_VERSION_MINOR, +           (gchar*)"private-slvideoplugin", +           (gchar*)"SL Video sink plugin", +           plugin_init, (gchar*)"1.0", (gchar*)"LGPL", +           (gchar*)"Second Life", +           (gchar*)"http://www.secondlife.com/");  #undef PACKAGE  void gst_slvideo_init_class (void)  { -	ll_gst_plugin_register_static (&gst_plugin_desc); -	DEBUGMSG("CLASS INIT"); +    ll_gst_plugin_register_static (&gst_plugin_desc); +    DEBUGMSG("CLASS INIT");  }  #endif // LL_GSTREAMER010_ENABLED diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h index 29d65fa4e9..d4e07daf4f 100644 --- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h +++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.h @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -55,43 +55,43 @@ typedef struct _GstSLVideo      GstSLVideo;  typedef struct _GstSLVideoClass GstSLVideoClass;  typedef enum { -	SLV_PF_UNKNOWN = 0, -	SLV_PF_RGBX    = 1, -	SLV_PF_BGRX    = 2, -	SLV__END       = 3 +    SLV_PF_UNKNOWN = 0, +    SLV_PF_RGBX    = 1, +    SLV_PF_BGRX    = 2, +    SLV__END       = 3  } SLVPixelFormat;  const int SLVPixelFormatBytes[SLV__END] = {1, 4, 4};  struct _GstSLVideo  { -	GstVideoSink video_sink; - -	GstCaps *caps; - -	int fps_n, fps_d; -	int par_n, par_d; -	int height, width; -	SLVPixelFormat format; - -	// SHARED WITH APPLICATION: -	// Access to the following should be protected by GST_OBJECT_LOCK() on -	// the GstSLVideo object, and should be totally consistent upon UNLOCK -	// (i.e. all written at once to reflect the current retained frame info -	// when the retained frame is updated.) -	bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.) -	unsigned char*  retained_frame_data; -	int retained_frame_allocbytes; -	int retained_frame_width, retained_frame_height; -	SLVPixelFormat retained_frame_format; -	// sticky resize info -	bool resize_forced_always; -	int resize_try_width; -	int resize_try_height; +    GstVideoSink video_sink; + +    GstCaps *caps; + +    int fps_n, fps_d; +    int par_n, par_d; +    int height, width; +    SLVPixelFormat format; + +    // SHARED WITH APPLICATION: +    // Access to the following should be protected by GST_OBJECT_LOCK() on +    // the GstSLVideo object, and should be totally consistent upon UNLOCK +    // (i.e. all written at once to reflect the current retained frame info +    // when the retained frame is updated.) +    bool retained_frame_ready; // new frame ready since flag last reset. (*TODO: could get the writer to wait on a semaphore instead of having the reader poll, potentially making dropped frames somewhat cheaper.) +    unsigned char*  retained_frame_data; +    int retained_frame_allocbytes; +    int retained_frame_width, retained_frame_height; +    SLVPixelFormat retained_frame_format; +    // sticky resize info +    bool resize_forced_always; +    int resize_try_width; +    int resize_try_height;  }; -struct _GstSLVideoClass  +struct _GstSLVideoClass  { -	GstVideoSinkClass parent_class; +    GstVideoSinkClass parent_class;  };  GType gst_slvideo_get_type (void); diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 352b63583e..97d1d7d7b5 100644 --- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -1,4 +1,4 @@ -/**  +/**   * @file media_plugin_gstreamer010.cpp   * @brief GStreamer-0.10 plugin for LLMedia API plugin system   * @@ -6,21 +6,21 @@   * $LicenseInfo:firstyear=2007&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   * @endcond @@ -53,114 +53,114 @@ extern "C" {  class MediaPluginGStreamer010 : public MediaPluginBase  {  public: -	MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); -	~MediaPluginGStreamer010(); +    MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); +    ~MediaPluginGStreamer010(); -	/* virtual */ void receiveMessage(const char *message_string); +    /* virtual */ void receiveMessage(const char *message_string); -	static bool startup(); -	static bool closedown(); +    static bool startup(); +    static bool closedown(); -	gboolean processGSTEvents(GstBus     *bus, -				  GstMessage *message); +    gboolean processGSTEvents(GstBus     *bus, +                  GstMessage *message);  private: -	std::string getVersion(); -	bool navigateTo( const std::string urlIn ); -	bool seek( double time_sec ); -	bool setVolume( float volume ); -	 -	// misc -	bool pause(); -	bool stop(); -	bool play(double rate); -	bool getTimePos(double &sec_out); - -	static const double MIN_LOOP_SEC = 1.0F; - -	bool mIsLooping; - -	enum ECommand { -		COMMAND_NONE, -		COMMAND_STOP, -		COMMAND_PLAY, -		COMMAND_FAST_FORWARD, -		COMMAND_FAST_REWIND, -		COMMAND_PAUSE, -		COMMAND_SEEK, -	}; -	ECommand mCommand; +    std::string getVersion(); +    bool navigateTo( const std::string urlIn ); +    bool seek( double time_sec ); +    bool setVolume( float volume ); + +    // misc +    bool pause(); +    bool stop(); +    bool play(double rate); +    bool getTimePos(double &sec_out); + +    static const double MIN_LOOP_SEC = 1.0F; + +    bool mIsLooping; + +    enum ECommand { +        COMMAND_NONE, +        COMMAND_STOP, +        COMMAND_PLAY, +        COMMAND_FAST_FORWARD, +        COMMAND_FAST_REWIND, +        COMMAND_PAUSE, +        COMMAND_SEEK, +    }; +    ECommand mCommand;  private: -	bool unload(); -	bool load(); +    bool unload(); +    bool load(); -	bool update(int milliseconds); +    bool update(int milliseconds);          void mouseDown( int x, int y );          void mouseUp( int x, int y );          void mouseMove( int x, int y );          void sizeChanged(); -	 -	static bool mDoneInit; -	 -	guint mBusWatchID; -	 -	float mVolume; - -	int mDepth; - -	// media NATURAL size -	int mNaturalWidth; -	int mNaturalHeight; -	// media current size -	int mCurrentWidth; -	int mCurrentHeight; -	int mCurrentRowbytes; -	  // previous media size so we can detect changes -	  int mPreviousWidth; -	  int mPreviousHeight; -	// desired render size from host -	int mWidth; -	int mHeight; -	// padded texture size we need to write into -	int mTextureWidth; -	int mTextureHeight; -	 -	int mTextureFormatPrimary; -	int mTextureFormatType; - -	bool mSeekWanted; -	double mSeekDestination; -	 -	// Very GStreamer-specific -	GMainLoop *mPump; // event pump for this media -	GstElement *mPlaybin; -	GstElement *mVisualizer; -	GstSLVideo *mVideoSink; + +    static bool mDoneInit; + +    guint mBusWatchID; + +    float mVolume; + +    int mDepth; + +    // media NATURAL size +    int mNaturalWidth; +    int mNaturalHeight; +    // media current size +    int mCurrentWidth; +    int mCurrentHeight; +    int mCurrentRowbytes; +      // previous media size so we can detect changes +      int mPreviousWidth; +      int mPreviousHeight; +    // desired render size from host +    int mWidth; +    int mHeight; +    // padded texture size we need to write into +    int mTextureWidth; +    int mTextureHeight; + +    int mTextureFormatPrimary; +    int mTextureFormatType; + +    bool mSeekWanted; +    double mSeekDestination; + +    // Very GStreamer-specific +    GMainLoop *mPump; // event pump for this media +    GstElement *mPlaybin; +    GstElement *mVisualizer; +    GstSLVideo *mVideoSink;  };  //static  bool MediaPluginGStreamer010::mDoneInit = false;  MediaPluginGStreamer010::MediaPluginGStreamer010( -	LLPluginInstance::sendMessageFunction host_send_func, -	void *host_user_data ) : -	MediaPluginBase(host_send_func, host_user_data), -	mBusWatchID ( 0 ), -	mCurrentRowbytes ( 4 ), -	mTextureFormatPrimary ( GL_RGBA ), -	mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), -	mSeekWanted(false), -	mSeekDestination(0.0), -	mPump ( NULL ), -	mPlaybin ( NULL ), -	mVisualizer ( NULL ), -	mVideoSink ( NULL ), -	mCommand ( COMMAND_NONE ) +    LLPluginInstance::sendMessageFunction host_send_func, +    void *host_user_data ) : +    MediaPluginBase(host_send_func, host_user_data), +    mBusWatchID ( 0 ), +    mCurrentRowbytes ( 4 ), +    mTextureFormatPrimary ( GL_RGBA ), +    mTextureFormatType ( GL_UNSIGNED_INT_8_8_8_8_REV ), +    mSeekWanted(false), +    mSeekDestination(0.0), +    mPump ( NULL ), +    mPlaybin ( NULL ), +    mVisualizer ( NULL ), +    mVideoSink ( NULL ), +    mCommand ( COMMAND_NONE )  { -	std::ostringstream str; -	INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid())); +    std::ostringstream str; +    INFOMSG("MediaPluginGStreamer010 constructor - my PID=%u", U32(getpid()));  }  /////////////////////////////////////////////////////////////////////////////// @@ -169,188 +169,188 @@ MediaPluginGStreamer010::MediaPluginGStreamer010(  #ifdef LL_GST_REPORT_STATE_CHANGES  static char* get_gst_state_name(GstState state)  { -	switch (state) { -	case GST_STATE_VOID_PENDING: return "VOID_PENDING"; -	case GST_STATE_NULL: return "NULL"; -	case GST_STATE_READY: return "READY"; -	case GST_STATE_PAUSED: return "PAUSED"; -	case GST_STATE_PLAYING: return "PLAYING"; -	} -	return "(unknown)"; +    switch (state) { +    case GST_STATE_VOID_PENDING: return "VOID_PENDING"; +    case GST_STATE_NULL: return "NULL"; +    case GST_STATE_READY: return "READY"; +    case GST_STATE_PAUSED: return "PAUSED"; +    case GST_STATE_PLAYING: return "PLAYING"; +    } +    return "(unknown)";  }  #endif // LL_GST_REPORT_STATE_CHANGES  gboolean  MediaPluginGStreamer010::processGSTEvents(GstBus     *bus, -					  GstMessage *message) +                      GstMessage *message)  { -	if (!message)  -		return TRUE; // shield against GStreamer bug - -	if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && -	    GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) -	{ -		DEBUGMSG("Got GST message type: %s", -			LLGST_MESSAGE_TYPE_NAME (message)); -	} -	else -	{ -		// TODO: grok 'duration' message type -		DEBUGMSG("Got GST message type: %s", -			 LLGST_MESSAGE_TYPE_NAME (message)); -	} - -	switch (GST_MESSAGE_TYPE (message)) { -	case GST_MESSAGE_BUFFERING: { -		// NEEDS GST 0.10.11+ -		if (llgst_message_parse_buffering) -		{ -			gint percent = 0; -			llgst_message_parse_buffering(message, &percent); -			DEBUGMSG("GST buffering: %d%%", percent); -		} -		break; -	} -	case GST_MESSAGE_STATE_CHANGED: { -		GstState old_state; -		GstState new_state; -		GstState pending_state; -		llgst_message_parse_state_changed(message, -						&old_state, -						&new_state, -						&pending_state); +    if (!message) +        return TRUE; // shield against GStreamer bug + +    if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && +        GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING) +    { +        DEBUGMSG("Got GST message type: %s", +            LLGST_MESSAGE_TYPE_NAME (message)); +    } +    else +    { +        // TODO: grok 'duration' message type +        DEBUGMSG("Got GST message type: %s", +             LLGST_MESSAGE_TYPE_NAME (message)); +    } + +    switch (GST_MESSAGE_TYPE (message)) { +    case GST_MESSAGE_BUFFERING: { +        // NEEDS GST 0.10.11+ +        if (llgst_message_parse_buffering) +        { +            gint percent = 0; +            llgst_message_parse_buffering(message, &percent); +            DEBUGMSG("GST buffering: %d%%", percent); +        } +        break; +    } +    case GST_MESSAGE_STATE_CHANGED: { +        GstState old_state; +        GstState new_state; +        GstState pending_state; +        llgst_message_parse_state_changed(message, +                        &old_state, +                        &new_state, +                        &pending_state);  #ifdef LL_GST_REPORT_STATE_CHANGES -		// not generally very useful, and rather spammy. -		DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", -			 get_gst_state_name(old_state), -			 get_gst_state_name(new_state), -			 get_gst_state_name(pending_state)); +        // not generally very useful, and rather spammy. +        DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", +             get_gst_state_name(old_state), +             get_gst_state_name(new_state), +             get_gst_state_name(pending_state));  #endif // LL_GST_REPORT_STATE_CHANGES -		switch (new_state) { -		case GST_STATE_VOID_PENDING: -			break; -		case GST_STATE_NULL: -			break; -		case GST_STATE_READY: -			setStatus(STATUS_LOADED); -			break; -		case GST_STATE_PAUSED: -			setStatus(STATUS_PAUSED); -			break; -		case GST_STATE_PLAYING: -			setStatus(STATUS_PLAYING); -			break; -		} -		break; -	} -	case GST_MESSAGE_ERROR: { -		GError *err = NULL; -		gchar *debug = NULL; - -		llgst_message_parse_error (message, &err, &debug); -		WARNMSG("GST error: %s", err?err->message:"(unknown)"); -		if (err) -			g_error_free (err); -		g_free (debug); - -		mCommand = COMMAND_STOP; - -		setStatus(STATUS_ERROR); - -		break; -	} -	case GST_MESSAGE_INFO: { -		if (llgst_message_parse_info) -		{ -			GError *err = NULL; -			gchar *debug = NULL; -			 -			llgst_message_parse_info (message, &err, &debug); -			INFOMSG("GST info: %s", err?err->message:"(unknown)"); -			if (err) -				g_error_free (err); -			g_free (debug); -		} -		break; -	} -	case GST_MESSAGE_WARNING: { -		GError *err = NULL; -		gchar *debug = NULL; - -		llgst_message_parse_warning (message, &err, &debug); -		WARNMSG("GST warning: %s", err?err->message:"(unknown)"); -		if (err) -			g_error_free (err); -		g_free (debug); - -		break; -	} -	case GST_MESSAGE_EOS: -		/* end-of-stream */ -		DEBUGMSG("GST end-of-stream."); -		if (mIsLooping) -		{ -			DEBUGMSG("looping media..."); -			double eos_pos_sec = 0.0F; -			bool got_eos_position = getTimePos(eos_pos_sec); - -			if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) -			{ -				// if we know that the movie is really short, don't -				// loop it else it can easily become a time-hog -				// because of GStreamer spin-up overhead -				DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); -				// inject a COMMAND_PAUSE -				mCommand = COMMAND_PAUSE; -			} -			else -			{ +        switch (new_state) { +        case GST_STATE_VOID_PENDING: +            break; +        case GST_STATE_NULL: +            break; +        case GST_STATE_READY: +            setStatus(STATUS_LOADED); +            break; +        case GST_STATE_PAUSED: +            setStatus(STATUS_PAUSED); +            break; +        case GST_STATE_PLAYING: +            setStatus(STATUS_PLAYING); +            break; +        } +        break; +    } +    case GST_MESSAGE_ERROR: { +        GError *err = NULL; +        gchar *debug = NULL; + +        llgst_message_parse_error (message, &err, &debug); +        WARNMSG("GST error: %s", err?err->message:"(unknown)"); +        if (err) +            g_error_free (err); +        g_free (debug); + +        mCommand = COMMAND_STOP; + +        setStatus(STATUS_ERROR); + +        break; +    } +    case GST_MESSAGE_INFO: { +        if (llgst_message_parse_info) +        { +            GError *err = NULL; +            gchar *debug = NULL; + +            llgst_message_parse_info (message, &err, &debug); +            INFOMSG("GST info: %s", err?err->message:"(unknown)"); +            if (err) +                g_error_free (err); +            g_free (debug); +        } +        break; +    } +    case GST_MESSAGE_WARNING: { +        GError *err = NULL; +        gchar *debug = NULL; + +        llgst_message_parse_warning (message, &err, &debug); +        WARNMSG("GST warning: %s", err?err->message:"(unknown)"); +        if (err) +            g_error_free (err); +        g_free (debug); + +        break; +    } +    case GST_MESSAGE_EOS: +        /* end-of-stream */ +        DEBUGMSG("GST end-of-stream."); +        if (mIsLooping) +        { +            DEBUGMSG("looping media..."); +            double eos_pos_sec = 0.0F; +            bool got_eos_position = getTimePos(eos_pos_sec); + +            if (got_eos_position && eos_pos_sec < MIN_LOOP_SEC) +            { +                // if we know that the movie is really short, don't +                // loop it else it can easily become a time-hog +                // because of GStreamer spin-up overhead +                DEBUGMSG("really short movie (%0.3fsec) - not gonna loop this, pausing instead.", eos_pos_sec); +                // inject a COMMAND_PAUSE +                mCommand = COMMAND_PAUSE; +            } +            else +            {  #undef LLGST_LOOP_BY_SEEKING  // loop with a stop-start instead of a seek, because it actually seems rather  // faster than seeking on remote streams.  #ifdef LLGST_LOOP_BY_SEEKING -				// first, try looping by an explicit rewind -				bool seeksuccess = seek(0.0); -				if (seeksuccess) -				{ -					play(1.0); -				} -				else +                // first, try looping by an explicit rewind +                bool seeksuccess = seek(0.0); +                if (seeksuccess) +                { +                    play(1.0); +                } +                else  #endif // LLGST_LOOP_BY_SEEKING -				{  // use clumsy stop-start to loop -					DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); -					stop(); -					play(1.0); -				} -			} -		} -		else // not a looping media -		{ -			// inject a COMMAND_STOP -			mCommand = COMMAND_STOP; -		} -		break; -	default: -		/* unhandled message */ -		break; -	} - -	/* we want to be notified again the next time there is a message -	 * on the bus, so return true (false means we want to stop watching -	 * for messages on the bus and our callback should not be called again) -	 */ -	return TRUE; +                {  // use clumsy stop-start to loop +                    DEBUGMSG("didn't loop by rewinding - stopping and starting instead..."); +                    stop(); +                    play(1.0); +                } +            } +        } +        else // not a looping media +        { +            // inject a COMMAND_STOP +            mCommand = COMMAND_STOP; +        } +        break; +    default: +        /* unhandled message */ +        break; +    } + +    /* we want to be notified again the next time there is a message +     * on the bus, so return true (false means we want to stop watching +     * for messages on the bus and our callback should not be called again) +     */ +    return TRUE;  }  extern "C" {  gboolean  llmediaimplgstreamer_bus_callback (GstBus     *bus, -				   GstMessage *message, -				   gpointer    data) +                   GstMessage *message, +                   gpointer    data)  { -	MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; -	return impl->processGSTEvents(bus, message); +    MediaPluginGStreamer010 *impl = (MediaPluginGStreamer010*)data; +    return impl->processGSTEvents(bus, message);  }  } // extern "C" @@ -359,159 +359,159 @@ llmediaimplgstreamer_bus_callback (GstBus     *bus,  bool  MediaPluginGStreamer010::navigateTo ( const std::string urlIn )  { -	if (!mDoneInit) -		return false; // error +    if (!mDoneInit) +        return false; // error -	setStatus(STATUS_LOADING); +    setStatus(STATUS_LOADING); -	DEBUGMSG("Setting media URI: %s", urlIn.c_str()); +    DEBUGMSG("Setting media URI: %s", urlIn.c_str()); -	mSeekWanted = false; +    mSeekWanted = false; -	if (NULL == mPump || -	    NULL == mPlaybin) -	{ -		setStatus(STATUS_ERROR); -		return false; // error -	} +    if (NULL == mPump || +        NULL == mPlaybin) +    { +        setStatus(STATUS_ERROR); +        return false; // error +    } -	// set URI -	g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); -	//g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); +    // set URI +    g_object_set (G_OBJECT (mPlaybin), "uri", urlIn.c_str(), NULL); +    //g_object_set (G_OBJECT (mPlaybin), "uri", "file:///tmp/movie", NULL); -	// navigateTo implicitly plays, too. -	play(1.0); +    // navigateTo implicitly plays, too. +    play(1.0); -	return true; +    return true;  }  bool  MediaPluginGStreamer010::update(int milliseconds)  { -	if (!mDoneInit) -		return false; // error - -	DEBUGMSG("updating media..."); -	 -	// sanity check -	if (NULL == mPump || -	    NULL == mPlaybin) -	{ -		DEBUGMSG("dead media..."); -		return false; -	} - -	// see if there's an outstanding seek wanted -	if (mSeekWanted && -	    // bleh, GST has to be happy that the movie is really truly playing -	    // or it may quietly ignore the seek (with rtsp:// at least). -	    (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) -	{ -		seek(mSeekDestination); -		mSeekWanted = false; -	} - -	// *TODO: time-limit - but there isn't a lot we can do here, most -	// time is spent in gstreamer's own opaque worker-threads.  maybe -	// we can do something sneaky like only unlock the video object -	// for 'milliseconds' and otherwise hold the lock. -	while (g_main_context_pending(g_main_loop_get_context(mPump))) -	{ -	       g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); -	} - -	// check for availability of a new frame -	 -	if (mVideoSink) -	{ -	        GST_OBJECT_LOCK(mVideoSink); -		if (mVideoSink->retained_frame_ready) -		{ -			DEBUGMSG("NEW FRAME READY"); - -			if (mVideoSink->retained_frame_width != mCurrentWidth || -			    mVideoSink->retained_frame_height != mCurrentHeight) -				// *TODO: also check for change in format -			{ -				// just resize container, don't consume frame -				int neww = mVideoSink->retained_frame_width; -				int newh = mVideoSink->retained_frame_height; - -				int newd = 4; -				mTextureFormatPrimary = GL_RGBA; -				mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; - -				/* -				int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; -				if (SLV_PF_BGRX == mVideoSink->retained_frame_format) -				{ -					mTextureFormatPrimary = GL_BGRA; -					mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; -				} -				else -				{ -					mTextureFormatPrimary = GL_RGBA; -					mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; -				} -				*/ - -				GST_OBJECT_UNLOCK(mVideoSink); - -				mCurrentRowbytes = neww * newd; -				DEBUGMSG("video container resized to %dx%d", -					 neww, newh); - -				mDepth = newd; -				mCurrentWidth = neww; -				mCurrentHeight = newh; -				sizeChanged(); -				return true; -			} - -			if (mPixels && -			    mCurrentHeight <= mHeight && -			    mCurrentWidth <= mWidth && -			    !mTextureSegmentName.empty()) -			{ -				// we're gonna totally consume this frame - reset 'ready' flag -				mVideoSink->retained_frame_ready = FALSE; -				int destination_rowbytes = mWidth * mDepth; -				for (int row=0; row<mCurrentHeight; ++row) -				{ -					memcpy(&mPixels -					        [destination_rowbytes * row], -					       &mVideoSink->retained_frame_data -					        [mCurrentRowbytes * row], -					       mCurrentRowbytes); -				} - -				GST_OBJECT_UNLOCK(mVideoSink); -				DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); - -				setDirty(0,0,mCurrentWidth,mCurrentHeight); -			} -			else -			{ -				// new frame ready, but we're not ready to -				// consume it. - -				GST_OBJECT_UNLOCK(mVideoSink); - -				DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); -			} - -			return true; -		} -		else -		{ -			// nothing to do yet. -			GST_OBJECT_UNLOCK(mVideoSink); -			return true; -		} -	} - -	return true; +    if (!mDoneInit) +        return false; // error + +    DEBUGMSG("updating media..."); + +    // sanity check +    if (NULL == mPump || +        NULL == mPlaybin) +    { +        DEBUGMSG("dead media..."); +        return false; +    } + +    // see if there's an outstanding seek wanted +    if (mSeekWanted && +        // bleh, GST has to be happy that the movie is really truly playing +        // or it may quietly ignore the seek (with rtsp:// at least). +        (GST_STATE(mPlaybin) == GST_STATE_PLAYING)) +    { +        seek(mSeekDestination); +        mSeekWanted = false; +    } + +    // *TODO: time-limit - but there isn't a lot we can do here, most +    // time is spent in gstreamer's own opaque worker-threads.  maybe +    // we can do something sneaky like only unlock the video object +    // for 'milliseconds' and otherwise hold the lock. +    while (g_main_context_pending(g_main_loop_get_context(mPump))) +    { +           g_main_context_iteration(g_main_loop_get_context(mPump), FALSE); +    } + +    // check for availability of a new frame + +    if (mVideoSink) +    { +            GST_OBJECT_LOCK(mVideoSink); +        if (mVideoSink->retained_frame_ready) +        { +            DEBUGMSG("NEW FRAME READY"); + +            if (mVideoSink->retained_frame_width != mCurrentWidth || +                mVideoSink->retained_frame_height != mCurrentHeight) +                // *TODO: also check for change in format +            { +                // just resize container, don't consume frame +                int neww = mVideoSink->retained_frame_width; +                int newh = mVideoSink->retained_frame_height; + +                int newd = 4; +                mTextureFormatPrimary = GL_RGBA; +                mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; + +                /* +                int newd = SLVPixelFormatBytes[mVideoSink->retained_frame_format]; +                if (SLV_PF_BGRX == mVideoSink->retained_frame_format) +                { +                    mTextureFormatPrimary = GL_BGRA; +                    mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; +                } +                else +                { +                    mTextureFormatPrimary = GL_RGBA; +                    mTextureFormatType = GL_UNSIGNED_INT_8_8_8_8_REV; +                } +                */ + +                GST_OBJECT_UNLOCK(mVideoSink); + +                mCurrentRowbytes = neww * newd; +                DEBUGMSG("video container resized to %dx%d", +                     neww, newh); + +                mDepth = newd; +                mCurrentWidth = neww; +                mCurrentHeight = newh; +                sizeChanged(); +                return true; +            } + +            if (mPixels && +                mCurrentHeight <= mHeight && +                mCurrentWidth <= mWidth && +                !mTextureSegmentName.empty()) +            { +                // we're gonna totally consume this frame - reset 'ready' flag +                mVideoSink->retained_frame_ready = FALSE; +                int destination_rowbytes = mWidth * mDepth; +                for (int row=0; row<mCurrentHeight; ++row) +                { +                    memcpy(&mPixels +                            [destination_rowbytes * row], +                           &mVideoSink->retained_frame_data +                            [mCurrentRowbytes * row], +                           mCurrentRowbytes); +                } + +                GST_OBJECT_UNLOCK(mVideoSink); +                DEBUGMSG("NEW FRAME REALLY TRULY CONSUMED, TELLING HOST"); + +                setDirty(0,0,mCurrentWidth,mCurrentHeight); +            } +            else +            { +                // new frame ready, but we're not ready to +                // consume it. + +                GST_OBJECT_UNLOCK(mVideoSink); + +                DEBUGMSG("NEW FRAME not consumed, still waiting for a shm segment and/or shm resize"); +            } + +            return true; +        } +        else +        { +            // nothing to do yet. +            GST_OBJECT_UNLOCK(mVideoSink); +            return true; +        } +    } + +    return true;  } @@ -537,253 +537,253 @@ MediaPluginGStreamer010::mouseMove( int x, int y )  bool  MediaPluginGStreamer010::pause()  { -	DEBUGMSG("pausing media..."); -	// todo: error-check this? -	if (mDoneInit && mPlaybin) -	{ -		llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); -		return true; -	} -	return false; +    DEBUGMSG("pausing media..."); +    // todo: error-check this? +    if (mDoneInit && mPlaybin) +    { +        llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); +        return true; +    } +    return false;  }  bool  MediaPluginGStreamer010::stop()  { -	DEBUGMSG("stopping media..."); -	// todo: error-check this? -	if (mDoneInit && mPlaybin) -	{ -		llgst_element_set_state(mPlaybin, GST_STATE_READY); -		return true; -	} -	return false; +    DEBUGMSG("stopping media..."); +    // todo: error-check this? +    if (mDoneInit && mPlaybin) +    { +        llgst_element_set_state(mPlaybin, GST_STATE_READY); +        return true; +    } +    return false;  }  bool  MediaPluginGStreamer010::play(double rate)  { -	// NOTE: we don't actually support non-natural rate. +    // NOTE: we don't actually support non-natural rate.          DEBUGMSG("playing media... rate=%f", rate); -	// todo: error-check this? -	if (mDoneInit && mPlaybin) -	{ -		llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); -		return true; -	} -	return false; +    // todo: error-check this? +    if (mDoneInit && mPlaybin) +    { +        llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); +        return true; +    } +    return false;  }  bool  MediaPluginGStreamer010::setVolume( float volume )  { -	// we try to only update volume as conservatively as -	// possible, as many gst-plugins-base versions up to at least -	// November 2008 have critical race-conditions in setting volume - sigh -	if (mVolume == volume) -		return true; // nothing to do, everything's fine - -	mVolume = volume; -	if (mDoneInit && mPlaybin) -	{ -		g_object_set(mPlaybin, "volume", mVolume, NULL); -		return true; -	} - -	return false; +    // we try to only update volume as conservatively as +    // possible, as many gst-plugins-base versions up to at least +    // November 2008 have critical race-conditions in setting volume - sigh +    if (mVolume == volume) +        return true; // nothing to do, everything's fine + +    mVolume = volume; +    if (mDoneInit && mPlaybin) +    { +        g_object_set(mPlaybin, "volume", mVolume, NULL); +        return true; +    } + +    return false;  }  bool  MediaPluginGStreamer010::seek(double time_sec)  { -	bool success = false; -	if (mDoneInit && mPlaybin) -	{ -		success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, -				GstSeekFlags(GST_SEEK_FLAG_FLUSH | -					     GST_SEEK_FLAG_KEY_UNIT), -				GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), -				GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); -	} -	DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", -		 float(time_sec), int(success)); -	return success; +    bool success = false; +    if (mDoneInit && mPlaybin) +    { +        success = llgst_element_seek(mPlaybin, 1.0F, GST_FORMAT_TIME, +                GstSeekFlags(GST_SEEK_FLAG_FLUSH | +                         GST_SEEK_FLAG_KEY_UNIT), +                GST_SEEK_TYPE_SET, gint64(time_sec*GST_SECOND), +                GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); +    } +    DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", +         float(time_sec), int(success)); +    return success;  }  bool  MediaPluginGStreamer010::getTimePos(double &sec_out)  { -	bool got_position = false; -	if (mDoneInit && mPlaybin) -	{ -		gint64 pos; -		GstFormat timefmt = GST_FORMAT_TIME; -		got_position = -			llgst_element_query_position && -			llgst_element_query_position(mPlaybin, -						     &timefmt, -						     &pos); -		got_position = got_position -			&& (timefmt == GST_FORMAT_TIME); -		// GStreamer may have other ideas, but we consider the current position -		// undefined if not PLAYING or PAUSED -		got_position = got_position && -			(GST_STATE(mPlaybin) == GST_STATE_PLAYING || -			 GST_STATE(mPlaybin) == GST_STATE_PAUSED); -		if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) -		{ -			if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) -			{ -				// if we're playing then we treat an invalid clock time -				// as 0, for complicated reasons (insert reason here) -				pos = 0; -			} -			else -			{ -				got_position = false; -			} -			 -		} -		// If all the preconditions succeeded... we can trust the result. -		if (got_position) -		{ -			sec_out = double(pos) / double(GST_SECOND); // gst to sec -		} -	} -	return got_position; +    bool got_position = false; +    if (mDoneInit && mPlaybin) +    { +        gint64 pos; +        GstFormat timefmt = GST_FORMAT_TIME; +        got_position = +            llgst_element_query_position && +            llgst_element_query_position(mPlaybin, +                             &timefmt, +                             &pos); +        got_position = got_position +            && (timefmt == GST_FORMAT_TIME); +        // GStreamer may have other ideas, but we consider the current position +        // undefined if not PLAYING or PAUSED +        got_position = got_position && +            (GST_STATE(mPlaybin) == GST_STATE_PLAYING || +             GST_STATE(mPlaybin) == GST_STATE_PAUSED); +        if (got_position && !GST_CLOCK_TIME_IS_VALID(pos)) +        { +            if (GST_STATE(mPlaybin) == GST_STATE_PLAYING) +            { +                // if we're playing then we treat an invalid clock time +                // as 0, for complicated reasons (insert reason here) +                pos = 0; +            } +            else +            { +                got_position = false; +            } + +        } +        // If all the preconditions succeeded... we can trust the result. +        if (got_position) +        { +            sec_out = double(pos) / double(GST_SECOND); // gst to sec +        } +    } +    return got_position;  }  bool  MediaPluginGStreamer010::load()  { -	if (!mDoneInit) -		return false; // error - -	setStatus(STATUS_LOADING); - -	DEBUGMSG("setting up media..."); - -	mIsLooping = false; -	mVolume = 0.1234567; // minor hack to force an initial volume update - -	// Create a pumpable main-loop for this media -	mPump = g_main_loop_new (NULL, FALSE); -	if (!mPump) -	{ -		setStatus(STATUS_ERROR); -		return false; // error -	} - -	// instantiate a playbin element to do the hard work -	mPlaybin = llgst_element_factory_make ("playbin", "play"); -	if (!mPlaybin) -	{ -		setStatus(STATUS_ERROR); -		return false; // error -	} - -	// get playbin's bus -	GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); -	if (!bus) -	{ -		setStatus(STATUS_ERROR); -		return false; // error -	} -	mBusWatchID = llgst_bus_add_watch (bus, -					   llmediaimplgstreamer_bus_callback, -					   this); -	llgst_object_unref (bus); +    if (!mDoneInit) +        return false; // error + +    setStatus(STATUS_LOADING); + +    DEBUGMSG("setting up media..."); + +    mIsLooping = false; +    mVolume = 0.1234567; // minor hack to force an initial volume update + +    // Create a pumpable main-loop for this media +    mPump = g_main_loop_new (NULL, FALSE); +    if (!mPump) +    { +        setStatus(STATUS_ERROR); +        return false; // error +    } + +    // instantiate a playbin element to do the hard work +    mPlaybin = llgst_element_factory_make ("playbin", "play"); +    if (!mPlaybin) +    { +        setStatus(STATUS_ERROR); +        return false; // error +    } + +    // get playbin's bus +    GstBus *bus = llgst_pipeline_get_bus (GST_PIPELINE (mPlaybin)); +    if (!bus) +    { +        setStatus(STATUS_ERROR); +        return false; // error +    } +    mBusWatchID = llgst_bus_add_watch (bus, +                       llmediaimplgstreamer_bus_callback, +                       this); +    llgst_object_unref (bus);  #if 0 // not quite stable/correct yet -	// get a visualizer element (bonus feature!) -	char* vis_name = getenv("LL_GST_VIS_NAME"); -	if (!vis_name || -	    (vis_name && std::string(vis_name)!="none")) -	{ -		if (vis_name) -		{ -			mVisualizer = llgst_element_factory_make (vis_name, "vis"); -		} -		if (!mVisualizer) -		{ -			mVisualizer = llgst_element_factory_make ("libvisual_jess", "vis"); -			if (!mVisualizer) -			{ -				mVisualizer = llgst_element_factory_make ("goom", "vis"); -				if (!mVisualizer) -				{ -					mVisualizer = llgst_element_factory_make ("libvisual_lv_scope", "vis"); -					if (!mVisualizer) -					{ -						// That's okay, we don't NEED this. -					} -				} -			} -		} -	} +    // get a visualizer element (bonus feature!) +    char* vis_name = getenv("LL_GST_VIS_NAME"); +    if (!vis_name || +        (vis_name && std::string(vis_name)!="none")) +    { +        if (vis_name) +        { +            mVisualizer = llgst_element_factory_make (vis_name, "vis"); +        } +        if (!mVisualizer) +        { +            mVisualizer = llgst_element_factory_make ("libvisual_jess", "vis"); +            if (!mVisualizer) +            { +                mVisualizer = llgst_element_factory_make ("goom", "vis"); +                if (!mVisualizer) +                { +                    mVisualizer = llgst_element_factory_make ("libvisual_lv_scope", "vis"); +                    if (!mVisualizer) +                    { +                        // That's okay, we don't NEED this. +                    } +                } +            } +        } +    }  #endif -	if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { -		// instantiate a custom video sink -		mVideoSink = -			GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); -		if (!mVideoSink) -		{ -			WARNMSG("Could not instantiate private-slvideo element."); -			// todo: cleanup. -			setStatus(STATUS_ERROR); -			return false; // error -		} - -		// connect the pieces -		g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); -	} - -	if (mVisualizer) -	{ -		g_object_set(mPlaybin, "vis-plugin", mVisualizer, NULL); -	} - -	return true; +    if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { +        // instantiate a custom video sink +        mVideoSink = +            GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); +        if (!mVideoSink) +        { +            WARNMSG("Could not instantiate private-slvideo element."); +            // todo: cleanup. +            setStatus(STATUS_ERROR); +            return false; // error +        } + +        // connect the pieces +        g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); +    } + +    if (mVisualizer) +    { +        g_object_set(mPlaybin, "vis-plugin", mVisualizer, NULL); +    } + +    return true;  }  bool  MediaPluginGStreamer010::unload ()  { -	if (!mDoneInit) -		return false; // error - -	DEBUGMSG("unloading media..."); -	 -	// stop getting callbacks for this bus -	g_source_remove(mBusWatchID); -	mBusWatchID = 0; - -	if (mPlaybin) -	{ -		llgst_element_set_state (mPlaybin, GST_STATE_NULL); -		llgst_object_unref (GST_OBJECT (mPlaybin)); -		mPlaybin = NULL; -	} - -	if (mVisualizer) -	{ -		llgst_object_unref (GST_OBJECT (mVisualizer)); -		mVisualizer = NULL; -	} - -	if (mPump) -	{ -		g_main_loop_quit(mPump); -		mPump = NULL; -	} - -	mVideoSink = NULL; - -	setStatus(STATUS_NONE); - -	return true; +    if (!mDoneInit) +        return false; // error + +    DEBUGMSG("unloading media..."); + +    // stop getting callbacks for this bus +    g_source_remove(mBusWatchID); +    mBusWatchID = 0; + +    if (mPlaybin) +    { +        llgst_element_set_state (mPlaybin, GST_STATE_NULL); +        llgst_object_unref (GST_OBJECT (mPlaybin)); +        mPlaybin = NULL; +    } + +    if (mVisualizer) +    { +        llgst_object_unref (GST_OBJECT (mVisualizer)); +        mVisualizer = NULL; +    } + +    if (mPump) +    { +        g_main_loop_quit(mPump); +        mPump = NULL; +    } + +    mVideoSink = NULL; + +    setStatus(STATUS_NONE); + +    return true;  } @@ -791,132 +791,132 @@ MediaPluginGStreamer010::unload ()  bool  MediaPluginGStreamer010::startup()  { -	// first - check if GStreamer is explicitly disabled -	if (NULL != getenv("LL_DISABLE_GSTREAMER")) -		return false; +    // first - check if GStreamer is explicitly disabled +    if (NULL != getenv("LL_DISABLE_GSTREAMER")) +        return false; -	// only do global GStreamer initialization once. -	if (!mDoneInit) -	{ -		g_thread_init(NULL); +    // only do global GStreamer initialization once. +    if (!mDoneInit) +    { +        g_thread_init(NULL); -		// Init the glib type system - we need it. -		g_type_init(); +        // Init the glib type system - we need it. +        g_type_init(); -		// Get symbols! +        // Get symbols!  #if LL_DARWIN -		if (! grab_gst_syms("libgstreamer-0.10.dylib", -				    "libgstvideo-0.10.dylib") ) +        if (! grab_gst_syms("libgstreamer-0.10.dylib", +                    "libgstvideo-0.10.dylib") )  #elseif LL_WINDOWS -		if (! grab_gst_syms("libgstreamer-0.10.dll", -				    "libgstvideo-0.10.dll") ) +        if (! grab_gst_syms("libgstreamer-0.10.dll", +                    "libgstvideo-0.10.dll") )  #else // linux or other ELFy unixoid -		if (! grab_gst_syms("libgstreamer-0.10.so.0", -				    "libgstvideo-0.10.so.0") ) +        if (! grab_gst_syms("libgstreamer-0.10.so.0", +                    "libgstvideo-0.10.so.0") )  #endif -		{ -			WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); -			return false; -		} - -		if (llgst_segtrap_set_enabled) -		{ -			llgst_segtrap_set_enabled(FALSE); -		} -		else -		{ -			WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); -		} +        { +            WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); +            return false; +        } + +        if (llgst_segtrap_set_enabled) +        { +            llgst_segtrap_set_enabled(FALSE); +        } +        else +        { +            WARNMSG("gst_segtrap_set_enabled() is not available; plugin crashes won't be caught."); +        }  #if LL_LINUX -		// Gstreamer tries a fork during init, waitpid-ing on it, -		// which conflicts with any installed SIGCHLD handler... -		struct sigaction tmpact, oldact; -		if (llgst_registry_fork_set_enabled) { -			// if we can disable SIGCHLD-using forking behaviour, -			// do it. -			llgst_registry_fork_set_enabled(false); -		} -		else { -			// else temporarily install default SIGCHLD handler -			// while GStreamer initialises -			tmpact.sa_handler = SIG_DFL; -			sigemptyset( &tmpact.sa_mask ); -			tmpact.sa_flags = SA_SIGINFO; -			sigaction(SIGCHLD, &tmpact, &oldact); -		} +        // Gstreamer tries a fork during init, waitpid-ing on it, +        // which conflicts with any installed SIGCHLD handler... +        struct sigaction tmpact, oldact; +        if (llgst_registry_fork_set_enabled) { +            // if we can disable SIGCHLD-using forking behaviour, +            // do it. +            llgst_registry_fork_set_enabled(false); +        } +        else { +            // else temporarily install default SIGCHLD handler +            // while GStreamer initialises +            tmpact.sa_handler = SIG_DFL; +            sigemptyset( &tmpact.sa_mask ); +            tmpact.sa_flags = SA_SIGINFO; +            sigaction(SIGCHLD, &tmpact, &oldact); +        }  #endif // LL_LINUX -		// Protect against GStreamer resetting the locale, yuck. -		static std::string saved_locale; -		saved_locale = setlocale(LC_ALL, NULL); +        // Protect against GStreamer resetting the locale, yuck. +        static std::string saved_locale; +        saved_locale = setlocale(LC_ALL, NULL); -		// finally, try to initialize GStreamer! -		GError *err = NULL; -		gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); +        // finally, try to initialize GStreamer! +        GError *err = NULL; +        gboolean init_gst_success = llgst_init_check(NULL, NULL, &err); -		// restore old locale -		setlocale(LC_ALL, saved_locale.c_str() ); +        // restore old locale +        setlocale(LC_ALL, saved_locale.c_str() );  #if LL_LINUX -		// restore old SIGCHLD handler -		if (!llgst_registry_fork_set_enabled) -			sigaction(SIGCHLD, &oldact, NULL); +        // restore old SIGCHLD handler +        if (!llgst_registry_fork_set_enabled) +            sigaction(SIGCHLD, &oldact, NULL);  #endif // LL_LINUX -		if (!init_gst_success) // fail -		{ -			if (err) -			{ -				WARNMSG("GST init failed: %s", err->message); -				g_error_free(err); -			} -			else -			{ -				WARNMSG("GST init failed for unspecified reason."); -			} -			return false; -		} -		 -		// Init our custom plugins - only really need do this once. -		gst_slvideo_init_class(); - -		mDoneInit = true; -	} - -	return true; +        if (!init_gst_success) // fail +        { +            if (err) +            { +                WARNMSG("GST init failed: %s", err->message); +                g_error_free(err); +            } +            else +            { +                WARNMSG("GST init failed for unspecified reason."); +            } +            return false; +        } + +        // Init our custom plugins - only really need do this once. +        gst_slvideo_init_class(); + +        mDoneInit = true; +    } + +    return true;  }  void  MediaPluginGStreamer010::sizeChanged()  { -	// the shared writing space has possibly changed size/location/whatever - -	// Check to see whether the movie's NATURAL size has been set yet -	if (1 == mNaturalWidth && -	    1 == mNaturalHeight) -	{ -		mNaturalWidth = mCurrentWidth; -		mNaturalHeight = mCurrentHeight; -		DEBUGMSG("Media NATURAL size better detected as %dx%d", -			 mNaturalWidth, mNaturalHeight); -	} - -	// if the size has changed then the shm has changed and the app needs telling -	if (mCurrentWidth != mPreviousWidth || -	    mCurrentHeight != mPreviousHeight) -	{ -		mPreviousWidth = mCurrentWidth; -		mPreviousHeight = mCurrentHeight; - -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); -		message.setValue("name", mTextureSegmentName); -		message.setValueS32("width", mNaturalWidth); -		message.setValueS32("height", mNaturalHeight); -		DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); -		sendMessage(message); -	} +    // the shared writing space has possibly changed size/location/whatever + +    // Check to see whether the movie's NATURAL size has been set yet +    if (1 == mNaturalWidth && +        1 == mNaturalHeight) +    { +        mNaturalWidth = mCurrentWidth; +        mNaturalHeight = mCurrentHeight; +        DEBUGMSG("Media NATURAL size better detected as %dx%d", +             mNaturalWidth, mNaturalHeight); +    } + +    // if the size has changed then the shm has changed and the app needs telling +    if (mCurrentWidth != mPreviousWidth || +        mCurrentHeight != mPreviousHeight) +    { +        mPreviousWidth = mCurrentWidth; +        mPreviousHeight = mCurrentHeight; + +        LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_request"); +        message.setValue("name", mTextureSegmentName); +        message.setValueS32("width", mNaturalWidth); +        message.setValueS32("height", mNaturalHeight); +        DEBUGMSG("<--- Sending size change request to application with name: '%s' - natural size is %d x %d", mTextureSegmentName.c_str(), mNaturalWidth, mNaturalHeight); +        sendMessage(message); +    }  } @@ -925,306 +925,306 @@ MediaPluginGStreamer010::sizeChanged()  bool  MediaPluginGStreamer010::closedown()  { -	if (!mDoneInit) -		return false; // error +    if (!mDoneInit) +        return false; // error -	ungrab_gst_syms(); +    ungrab_gst_syms(); -	mDoneInit = false; +    mDoneInit = false; -	return true; +    return true;  }  MediaPluginGStreamer010::~MediaPluginGStreamer010()  { -	DEBUGMSG("MediaPluginGStreamer010 destructor"); +    DEBUGMSG("MediaPluginGStreamer010 destructor"); -	closedown(); +    closedown(); -	DEBUGMSG("GStreamer010 closing down"); +    DEBUGMSG("GStreamer010 closing down");  }  std::string  MediaPluginGStreamer010::getVersion()  { -	std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; -	if (mDoneInit && -	    llgst_version) -	{ -		guint major, minor, micro, nano; -		llgst_version(&major, &minor, µ, &nano); -		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); -	} -	else -	{ -		plugin_version += "(unknown)"; -	} -	return plugin_version; +    std::string plugin_version = "GStreamer010 media plugin, GStreamer version "; +    if (mDoneInit && +        llgst_version) +    { +        guint major, minor, micro, nano; +        llgst_version(&major, &minor, µ, &nano); +        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); +    } +    else +    { +        plugin_version += "(unknown)"; +    } +    return plugin_version;  }  void MediaPluginGStreamer010::receiveMessage(const char *message_string)  { -	//std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; - -	LLPluginMessage message_in; - -	if(message_in.parse(message_string) >= 0) -	{ -		std::string message_class = message_in.getClass(); -		std::string message_name = message_in.getName(); -		if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) -		{ -			if(message_name == "init") -			{ -				LLPluginMessage message("base", "init_response"); -				LLSD versions = LLSD::emptyMap(); -				versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; -				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; -				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; -				message.setValueLLSD("versions", versions); - -				if ( load() ) -				{ -					DEBUGMSG("GStreamer010 media instance set up"); -				} -				else -				{ -					WARNMSG("GStreamer010 media instance failed to set up"); -				} - -				message.setValue("plugin_version", getVersion()); -				sendMessage(message); -			} -			else if(message_name == "idle") -			{ -				// no response is necessary here. -				double time = message_in.getValueReal("time"); -				 -				// Convert time to milliseconds for update() -				update((int)(time * 1000.0f)); -			} -			else if(message_name == "cleanup") -			{ -				unload(); -				closedown(); -			} -			else if(message_name == "shm_added") -			{ -				SharedSegmentInfo info; -				info.mAddress = message_in.getValuePointer("address"); -				info.mSize = (size_t)message_in.getValueS32("size"); -				std::string name = message_in.getValue("name"); - -				std::ostringstream str; -				INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); - -				mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); -			} -			else if(message_name == "shm_remove") -			{ -				std::string name = message_in.getValue("name"); - -				DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); -				 -				SharedSegmentMap::iterator iter = mSharedSegments.find(name); -				if(iter != mSharedSegments.end()) -				{ -					if(mPixels == iter->second.mAddress) -					{ -						// This is the currently active pixel buffer.  Make sure we stop drawing to it. -						mPixels = NULL; -						mTextureSegmentName.clear(); -						 -						// Make sure the movie decoder is no longer pointed at the shared segment. -						sizeChanged();						 -					} -					mSharedSegments.erase(iter); -				} -				else -				{ -					WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); -				} - -				// Send the response so it can be cleaned up. -				LLPluginMessage message("base", "shm_remove_response"); -				message.setValue("name", name); -				sendMessage(message); -			} -			else -			{ -				std::ostringstream str; -				INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); -			} -		} -		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) -		{ -			if(message_name == "init") -			{ -				// Plugin gets to decide the texture parameters to use. -				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); -				// lame to have to decide this now, it depends on the movie.  Oh well. -				mDepth = 4; - -				mCurrentWidth = 1; -				mCurrentHeight = 1; -				mPreviousWidth = 1; -				mPreviousHeight = 1; -				mNaturalWidth = 1; -				mNaturalHeight = 1; -				mWidth = 1; -				mHeight = 1; -				mTextureWidth = 1; -				mTextureHeight = 1; - -				message.setValueU32("format", GL_RGBA); -				message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); - -				message.setValueS32("depth", mDepth); -				message.setValueS32("default_width", mWidth); -				message.setValueS32("default_height", mHeight); -				message.setValueU32("internalformat", GL_RGBA8); -				message.setValueBoolean("coords_opengl", true);	// true == use OpenGL-style coordinates, false == (0,0) is upper left. -				message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale -				sendMessage(message); -			} -			else if(message_name == "size_change") -			{ -				std::string name = message_in.getValue("name"); -				S32 width = message_in.getValueS32("width"); -				S32 height = message_in.getValueS32("height"); -				S32 texture_width = message_in.getValueS32("texture_width"); -				S32 texture_height = message_in.getValueS32("texture_height"); - -				std::ostringstream str; -				INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); - -				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); -				message.setValue("name", name); -				message.setValueS32("width", width); -				message.setValueS32("height", height); -				message.setValueS32("texture_width", texture_width); -				message.setValueS32("texture_height", texture_height); -				sendMessage(message); - -				if(!name.empty()) -				{ -					// Find the shared memory region with this name -					SharedSegmentMap::iterator iter = mSharedSegments.find(name); -					if(iter != mSharedSegments.end()) -					{ -						INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); -						INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); - -						mPixels = (unsigned char*)iter->second.mAddress; -						mTextureSegmentName = name; -						mWidth = width; -						mHeight = height; - -						if (texture_width > 1 || -						    texture_height > 1) // not a dummy size from the app, a real explicit forced size -						{ -							INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); -							 -							GST_OBJECT_LOCK(mVideoSink); -							mVideoSink->resize_forced_always = true; -							mVideoSink->resize_try_width = texture_width; -							mVideoSink->resize_try_height = texture_height; -							GST_OBJECT_UNLOCK(mVideoSink); - 						} - -						mTextureWidth = texture_width; -						mTextureHeight = texture_height; -					} -				} -			} -			else if(message_name == "load_uri") -			{ -				std::string uri = message_in.getValue("uri"); -				navigateTo( uri ); -				sendStatus();		 -			} -			else if(message_name == "mouse_event") -			{ -				std::string event = message_in.getValue("event"); -				S32 x = message_in.getValueS32("x"); -				S32 y = message_in.getValueS32("y"); -				 -				if(event == "down") -				{ -					mouseDown(x, y); -				} -				else if(event == "up") -				{ -					mouseUp(x, y); -				} -				else if(event == "move") -				{ -					mouseMove(x, y); -				}; -			}; -		} -		else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) -		{ -			if(message_name == "stop") -			{ -				stop(); -			} -			else if(message_name == "start") -			{ -				double rate = 0.0; -				if(message_in.hasValue("rate")) -				{ -					rate = message_in.getValueReal("rate"); -				} -				// NOTE: we don't actually support rate. -				play(rate); -			} -			else if(message_name == "pause") -			{ -				pause(); -			} -			else if(message_name == "seek") -			{ -				double time = message_in.getValueReal("time"); -				// defer the actual seek in case we haven't -				// really truly started yet in which case there -				// is nothing to seek upon -				mSeekWanted = true; -				mSeekDestination = time; -			} -			else if(message_name == "set_loop") -			{ -				bool loop = message_in.getValueBoolean("loop"); -				mIsLooping = loop; -			} -			else if(message_name == "set_volume") -			{ -				double volume = message_in.getValueReal("volume"); -				setVolume(volume); -			} -		} -		else -		{ -			INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); -		} -	} +    //std::cerr << "MediaPluginGStreamer010::receiveMessage: received message: \"" << message_string << "\"" << std::endl; + +    LLPluginMessage message_in; + +    if(message_in.parse(message_string) >= 0) +    { +        std::string message_class = message_in.getClass(); +        std::string message_name = message_in.getName(); +        if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE) +        { +            if(message_name == "init") +            { +                LLPluginMessage message("base", "init_response"); +                LLSD versions = LLSD::emptyMap(); +                versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION; +                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION; +                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION; +                message.setValueLLSD("versions", versions); + +                if ( load() ) +                { +                    DEBUGMSG("GStreamer010 media instance set up"); +                } +                else +                { +                    WARNMSG("GStreamer010 media instance failed to set up"); +                } + +                message.setValue("plugin_version", getVersion()); +                sendMessage(message); +            } +            else if(message_name == "idle") +            { +                // no response is necessary here. +                double time = message_in.getValueReal("time"); + +                // Convert time to milliseconds for update() +                update((int)(time * 1000.0f)); +            } +            else if(message_name == "cleanup") +            { +                unload(); +                closedown(); +            } +            else if(message_name == "shm_added") +            { +                SharedSegmentInfo info; +                info.mAddress = message_in.getValuePointer("address"); +                info.mSize = (size_t)message_in.getValueS32("size"); +                std::string name = message_in.getValue("name"); + +                std::ostringstream str; +                INFOMSG("MediaPluginGStreamer010::receiveMessage: shared memory added, name: %s, size: %d, address: %p", name.c_str(), int(info.mSize), info.mAddress); + +                mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); +            } +            else if(message_name == "shm_remove") +            { +                std::string name = message_in.getValue("name"); + +                DEBUGMSG("MediaPluginGStreamer010::receiveMessage: shared memory remove, name = %s", name.c_str()); + +                SharedSegmentMap::iterator iter = mSharedSegments.find(name); +                if(iter != mSharedSegments.end()) +                { +                    if(mPixels == iter->second.mAddress) +                    { +                        // This is the currently active pixel buffer.  Make sure we stop drawing to it. +                        mPixels = NULL; +                        mTextureSegmentName.clear(); + +                        // Make sure the movie decoder is no longer pointed at the shared segment. +                        sizeChanged(); +                    } +                    mSharedSegments.erase(iter); +                } +                else +                { +                    WARNMSG("MediaPluginGStreamer010::receiveMessage: unknown shared memory region!"); +                } + +                // Send the response so it can be cleaned up. +                LLPluginMessage message("base", "shm_remove_response"); +                message.setValue("name", name); +                sendMessage(message); +            } +            else +            { +                std::ostringstream str; +                INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown base message: %s", message_name.c_str()); +            } +        } +        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) +        { +            if(message_name == "init") +            { +                // Plugin gets to decide the texture parameters to use. +                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params"); +                // lame to have to decide this now, it depends on the movie.  Oh well. +                mDepth = 4; + +                mCurrentWidth = 1; +                mCurrentHeight = 1; +                mPreviousWidth = 1; +                mPreviousHeight = 1; +                mNaturalWidth = 1; +                mNaturalHeight = 1; +                mWidth = 1; +                mHeight = 1; +                mTextureWidth = 1; +                mTextureHeight = 1; + +                message.setValueU32("format", GL_RGBA); +                message.setValueU32("type", GL_UNSIGNED_INT_8_8_8_8_REV); + +                message.setValueS32("depth", mDepth); +                message.setValueS32("default_width", mWidth); +                message.setValueS32("default_height", mHeight); +                message.setValueU32("internalformat", GL_RGBA8); +                message.setValueBoolean("coords_opengl", true); // true == use OpenGL-style coordinates, false == (0,0) is upper left. +                message.setValueBoolean("allow_downsample", true); // we respond with grace and performance if asked to downscale +                sendMessage(message); +            } +            else if(message_name == "size_change") +            { +                std::string name = message_in.getValue("name"); +                S32 width = message_in.getValueS32("width"); +                S32 height = message_in.getValueS32("height"); +                S32 texture_width = message_in.getValueS32("texture_width"); +                S32 texture_height = message_in.getValueS32("texture_height"); + +                std::ostringstream str; +                INFOMSG("---->Got size change instruction from application with shm name: %s - size is %d x %d", name.c_str(), width, height); + +                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response"); +                message.setValue("name", name); +                message.setValueS32("width", width); +                message.setValueS32("height", height); +                message.setValueS32("texture_width", texture_width); +                message.setValueS32("texture_height", texture_height); +                sendMessage(message); + +                if(!name.empty()) +                { +                    // Find the shared memory region with this name +                    SharedSegmentMap::iterator iter = mSharedSegments.find(name); +                    if(iter != mSharedSegments.end()) +                    { +                        INFOMSG("*** Got size change with matching shm, new size is %d x %d", width, height); +                        INFOMSG("*** Got size change with matching shm, texture size size is %d x %d", texture_width, texture_height); + +                        mPixels = (unsigned char*)iter->second.mAddress; +                        mTextureSegmentName = name; +                        mWidth = width; +                        mHeight = height; + +                        if (texture_width > 1 || +                            texture_height > 1) // not a dummy size from the app, a real explicit forced size +                        { +                            INFOMSG("**** = REAL RESIZE REQUEST FROM APP"); + +                            GST_OBJECT_LOCK(mVideoSink); +                            mVideoSink->resize_forced_always = true; +                            mVideoSink->resize_try_width = texture_width; +                            mVideoSink->resize_try_height = texture_height; +                            GST_OBJECT_UNLOCK(mVideoSink); +                        } + +                        mTextureWidth = texture_width; +                        mTextureHeight = texture_height; +                    } +                } +            } +            else if(message_name == "load_uri") +            { +                std::string uri = message_in.getValue("uri"); +                navigateTo( uri ); +                sendStatus(); +            } +            else if(message_name == "mouse_event") +            { +                std::string event = message_in.getValue("event"); +                S32 x = message_in.getValueS32("x"); +                S32 y = message_in.getValueS32("y"); + +                if(event == "down") +                { +                    mouseDown(x, y); +                } +                else if(event == "up") +                { +                    mouseUp(x, y); +                } +                else if(event == "move") +                { +                    mouseMove(x, y); +                }; +            }; +        } +        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) +        { +            if(message_name == "stop") +            { +                stop(); +            } +            else if(message_name == "start") +            { +                double rate = 0.0; +                if(message_in.hasValue("rate")) +                { +                    rate = message_in.getValueReal("rate"); +                } +                // NOTE: we don't actually support rate. +                play(rate); +            } +            else if(message_name == "pause") +            { +                pause(); +            } +            else if(message_name == "seek") +            { +                double time = message_in.getValueReal("time"); +                // defer the actual seek in case we haven't +                // really truly started yet in which case there +                // is nothing to seek upon +                mSeekWanted = true; +                mSeekDestination = time; +            } +            else if(message_name == "set_loop") +            { +                bool loop = message_in.getValueBoolean("loop"); +                mIsLooping = loop; +            } +            else if(message_name == "set_volume") +            { +                double volume = message_in.getValueReal("volume"); +                setVolume(volume); +            } +        } +        else +        { +            INFOMSG("MediaPluginGStreamer010::receiveMessage: unknown message class: %s", message_class.c_str()); +        } +    }  }  int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)  { -	if (MediaPluginGStreamer010::startup()) -	{ -		MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); -		*plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; -		*plugin_user_data = (void*)self; -		 -		return 0; // okay -	} -	else  -	{ -		return -1; // failed to init -	} +    if (MediaPluginGStreamer010::startup()) +    { +        MediaPluginGStreamer010 *self = new MediaPluginGStreamer010(host_send_func, host_user_data); +        *plugin_send_func = MediaPluginGStreamer010::staticReceiveMessage; +        *plugin_user_data = (void*)self; + +        return 0; // okay +    } +    else +    { +        return -1; // failed to init +    }  }  #else // LL_GSTREAMER010_ENABLED @@ -1234,15 +1234,15 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void  class MediaPluginGStreamer010 : public MediaPluginBase  {  public: -	MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); -	~MediaPluginGStreamer010(); -	/* virtual */ void receiveMessage(const char *message_string); +    MediaPluginGStreamer010(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); +    ~MediaPluginGStreamer010(); +    /* virtual */ void receiveMessage(const char *message_string);  };  MediaPluginGStreamer010::MediaPluginGStreamer010( -	LLPluginInstance::sendMessageFunction host_send_func, -	void *host_user_data ) : -	MediaPluginBase(host_send_func, host_user_data) +    LLPluginInstance::sendMessageFunction host_send_func, +    void *host_user_data ) : +    MediaPluginBase(host_send_func, host_user_data)  {      // no-op  } @@ -1254,7 +1254,7 @@ MediaPluginGStreamer010::~MediaPluginGStreamer010()  void MediaPluginGStreamer010::receiveMessage(const char *message_string)  { -    // no-op  +    // no-op  }  // We're building without GStreamer enabled.  Just refuse to initialize. | 
