change configure to better detect gstreamer. Check create is valid in mediaplayer sample. Comment the heck out of the unix mediaplayer.cpp.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31968 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
181
configure.in
181
configure.in
@@ -1982,11 +1982,6 @@ SEARCH_INCLUDE="\
|
|||||||
/usr/include/wine \
|
/usr/include/wine \
|
||||||
/usr/local/include/wine \
|
/usr/local/include/wine \
|
||||||
\
|
\
|
||||||
/usr/include/gstreamer-0.8 \
|
|
||||||
/usr/local/include/gstreamer-0.8 \
|
|
||||||
/usr/include/libxml2 \
|
|
||||||
/usr/local/include/libxml2 \
|
|
||||||
\
|
|
||||||
/usr/unsupported/include \
|
/usr/unsupported/include \
|
||||||
/usr/athena/include \
|
/usr/athena/include \
|
||||||
/usr/local/x11r5/include \
|
/usr/local/x11r5/include \
|
||||||
@@ -6004,120 +5999,76 @@ if test "$wxUSE_MEDIACTRL" = "yes"; then
|
|||||||
if test "$wxUSE_GTK" = 1; then
|
if test "$wxUSE_GTK" = 1; then
|
||||||
wxUSE_GSTREAMER="yes"
|
wxUSE_GSTREAMER="yes"
|
||||||
|
|
||||||
dnl ---------------------------------------------------------------
|
dnl -------------------------------------------------------------------
|
||||||
dnl check for libxml2 lib
|
dnl Test for gstreamer module from pkg-config
|
||||||
dnl ---------------------------------------------------------------
|
dnl -------------------------------------------------------------------
|
||||||
AC_MSG_CHECKING([for libxml2])
|
PKG_CHECK_MODULES(GSTREAMER, gstreamer-0.8,
|
||||||
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],xml2)
|
[
|
||||||
if test "$ac_find_libraries" != "" ; then
|
CPPFLAGS="$CPPFLAGS $GSTREAMER_CFLAGS"
|
||||||
dnl -----------------------------------------------------------
|
LIBS="$LIBS $GSTREAMER_LIBS -lgstplay-0.8"
|
||||||
dnl Check for libxml2's xmlstring.h header
|
],
|
||||||
dnl Break out if not found
|
[
|
||||||
dnl -----------------------------------------------------------
|
AC_MSG_WARN([GStreamer installation not found])
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_MSG_CHECKING(for libxml2 headers)
|
|
||||||
WX_PATH_FIND_INCLUDES($SEARCH_INCLUDE, libxml/xmlstring.h)
|
|
||||||
if test "$ac_find_includes" != "" ; then
|
|
||||||
AC_MSG_RESULT(found in $ac_find_includes)
|
|
||||||
WX_INCLUDE_PATH_EXIST($ac_find_includes, $TOOLKIT_INCLUDE)
|
|
||||||
TOOLKIT_INCLUDE="$TOOLKIT_INCLUDE$ac_path_to_include"
|
|
||||||
else
|
|
||||||
AC_TRY_COMPILE(
|
|
||||||
[
|
|
||||||
#include <libxml/xmlstring.h>
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
[AC_MSG_RESULT(found in default search path)],
|
|
||||||
[wxUSE_GSTREAMER="no"])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
dnl -----------------------------------------------------------
|
|
||||||
dnl libxml2 lib not found - break out
|
|
||||||
dnl -----------------------------------------------------------
|
|
||||||
wxUSE_GSTREAMER="no"
|
wxUSE_GSTREAMER="no"
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
dnl Perform a check for a GStreamer element using gst-inspect
|
||||||
|
dnl Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
dnl Last modification: 25/01/2005
|
||||||
|
dnl
|
||||||
|
dnl AM_GST_ELEMENT_CHECK(ELEMENT-NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND)
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
AC_DEFUN([AM_GST_ELEMENT_CHECK],
|
||||||
|
[
|
||||||
|
if test "x$GST_INSPECT" == "x"; then
|
||||||
|
AC_CHECK_PROG(GST_INSPECT, gst-inspect, gst-inspect, [])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$GST_INSPECT" != "x"; then
|
||||||
|
AC_MSG_CHECKING(GStreamer element $1)
|
||||||
|
if [ $GST_INSPECT $1 > /dev/null 2> /dev/null ]; then
|
||||||
|
AC_MSG_RESULT(found.)
|
||||||
|
$2
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(not found.)
|
||||||
|
$3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
dnl Test for x video sink (video useless without)
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
AM_GST_ELEMENT_CHECK(xvimagesink,[],
|
||||||
|
[
|
||||||
|
wxUSE_GSTREAMER="no"
|
||||||
|
AC_MSG_WARN([x video sink not found - cannot use GStreamer])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
dnl Check for gstplay-0.8 lib and corresponding x overlay header
|
||||||
|
dnl -------------------------------------------------------------------
|
||||||
|
AC_CHECK_HEADER(gst/xoverlay/xoverlay.h, [],
|
||||||
|
[
|
||||||
|
wxUSE_GSTREAMER="no"
|
||||||
|
AC_MSG_WARN([xoverlay header not found, cannot use GStreamer])
|
||||||
|
],
|
||||||
|
[#include <gst/gst.h>])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for gstplay 0.8])
|
||||||
|
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],gstplay-0.8)
|
||||||
|
|
||||||
|
if test "$ac_find_libraries" = "" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
wxUSE_GSTREAMER="no"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$wxUSE_GSTREAMER" = "yes"; then
|
if test "$wxUSE_GSTREAMER" = "yes"; then
|
||||||
dnl -----------------------------------------------------------
|
AC_DEFINE(wxUSE_GSTREAMER)
|
||||||
dnl test for gstreamer main lib
|
AC_MSG_RESULT([GStreamer detection successful])
|
||||||
dnl -----------------------------------------------------------
|
|
||||||
AC_MSG_CHECKING([for gstreamer 0.8])
|
|
||||||
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],gstreamer-0.8)
|
|
||||||
if test "$ac_find_libraries" != "" ; then
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
dnl Check for GStreamer gstplay lib
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_MSG_CHECKING([for gstplay 0.8])
|
|
||||||
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],gstplay-0.8)
|
|
||||||
if test "$ac_find_libraries" != "" ; then
|
|
||||||
dnl ---------------------------------------------------
|
|
||||||
dnl gstplay lib found - check for gstinterfaces lib
|
|
||||||
dnl ---------------------------------------------------
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_MSG_CHECKING([for gstinterfaces 0.8])
|
|
||||||
WX_PATH_FIND_LIBRARIES([$SEARCH_LIB],gstinterfaces-0.8)
|
|
||||||
if test "$ac_find_libraries" != "" ; then
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
dnl GStreamer libs found - check for gstreamer
|
|
||||||
dnl include path and header
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
AC_MSG_CHECKING(for GStreamer headers)
|
|
||||||
WX_PATH_FIND_INCLUDES($SEARCH_INCLUDE, gst/gst.h)
|
|
||||||
if test "$ac_find_includes" != "" ; then
|
|
||||||
AC_MSG_RESULT(found in $ac_find_includes)
|
|
||||||
WX_INCLUDE_PATH_EXIST($ac_find_includes, $TOOLKIT_INCLUDE)
|
|
||||||
TOOLKIT_INCLUDE="$TOOLKIT_INCLUDE$ac_path_to_include"
|
|
||||||
else
|
|
||||||
AC_TRY_COMPILE(
|
|
||||||
[
|
|
||||||
#include <gst/gst.h>
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
[AC_MSG_RESULT(found in default search path)],
|
|
||||||
[wxUSE_GSTREAMER="no"])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
dnl gstinterfaces lib not found - break out
|
|
||||||
dnl -----------------------------------------------
|
|
||||||
wxUSE_GSTREAMER="no"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
dnl ---------------------------------------------------
|
|
||||||
dnl gstplay lib not found - break out
|
|
||||||
dnl ---------------------------------------------------
|
|
||||||
wxUSE_GSTREAMER="no"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
dnl Main GStreamer lib not found - break out
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
wxUSE_GSTREAMER="no"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl -----------------------------------------------------------
|
|
||||||
dnl Check if everything went ok - if not then print no
|
|
||||||
dnl and break out
|
|
||||||
dnl -----------------------------------------------------------
|
|
||||||
if test "$wxUSE_GSTREAMER" = "yes"; then
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
dnl Success! Define wxUSE_GSTREAMER to 1 so that
|
|
||||||
dnl src/unix/mediactrl.cpp will build with GStreamer
|
|
||||||
dnl enabled, and add the 3 gstreamer libs and the libxml2
|
|
||||||
dnl to the linker's library includes
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
AC_DEFINE(wxUSE_GSTREAMER)
|
|
||||||
LIBS="$LIBS -lgstreamer-0.8 -lgstplay-0.8"
|
|
||||||
LIBS="$LIBS -lgstinterfaces-0.8 -lxml2"
|
|
||||||
else
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
dnl Generic "NO" message - triggered if any of the above
|
|
||||||
dnl conditions doesn't pan out
|
|
||||||
dnl -------------------------------------------------------
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS mediaplayer"
|
SAMPLES_SUBDIRS="$SAMPLES_SUBDIRS mediaplayer"
|
||||||
|
@@ -870,7 +870,12 @@ MyNotebookPage::MyNotebookPage(wxNotebook* theBook) :
|
|||||||
//
|
//
|
||||||
// Create our media control
|
// Create our media control
|
||||||
//
|
//
|
||||||
m_mediactrl = new wxMediaCtrl(this, wxID_MEDIACTRL);
|
m_mediactrl = new wxMediaCtrl();
|
||||||
|
|
||||||
|
// Make sure creation was successful
|
||||||
|
bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL);
|
||||||
|
wxASSERT_MSG(bOK, wxT("Could not create media control!"));
|
||||||
|
|
||||||
vertsizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
|
vertsizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@@ -46,7 +46,13 @@
|
|||||||
//
|
//
|
||||||
// wxGStreamerMediaBackend
|
// wxGStreamerMediaBackend
|
||||||
//
|
//
|
||||||
// Uses nanoseconds...
|
//TODO:
|
||||||
|
//TODO: This is really not the best way to play-stop -
|
||||||
|
//TODO: it should just have one playbin and stick with it the whole
|
||||||
|
//TODO: instance of wxGStreamerMediaBackend - but stopping appears
|
||||||
|
//TODO: to invalidate the playbin object...
|
||||||
|
//TODO:
|
||||||
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
#if wxUSE_GSTREAMER
|
#if wxUSE_GSTREAMER
|
||||||
|
|
||||||
@@ -67,12 +73,6 @@
|
|||||||
# include <gtk/gtksignal.h>
|
# include <gtk/gtksignal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//FIXME:
|
|
||||||
//FIXME: This is really not the best way to play-stop -
|
|
||||||
//FIXME: it should just have one playbin and stick with it the whole
|
|
||||||
//FIXME: instance of wxGStreamerMediaBackend - but stopping appears
|
|
||||||
//FIXME: to invalidate the playbin object...
|
|
||||||
//FIXME:
|
|
||||||
|
|
||||||
class WXDLLIMPEXP_MEDIA wxGStreamerMediaBackend : public wxMediaBackend
|
class WXDLLIMPEXP_MEDIA wxGStreamerMediaBackend : public wxMediaBackend
|
||||||
{
|
{
|
||||||
@@ -124,18 +124,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
GstElement* m_player; //GStreamer media element
|
GstElement* m_player; //GStreamer media element
|
||||||
GstElement* m_audiosink;
|
// GstElement* m_audiosink;
|
||||||
GstElement* m_videosink;
|
GstElement* m_videosink;
|
||||||
|
|
||||||
wxSize m_videoSize;
|
wxSize m_videoSize;
|
||||||
wxControl* m_ctrl;
|
wxControl* m_ctrl;
|
||||||
|
|
||||||
//FIXME:
|
|
||||||
//FIXME: In lue of the last big FIXME, when you pause and seek gstreamer
|
|
||||||
//FIXME: doesn't update the position sometimes, so we need to keep track of whether
|
|
||||||
//FIXME: we have paused or not and keep track of the time after the pause
|
|
||||||
//FIXME: and whenever the user seeks while paused
|
|
||||||
//FIXME:
|
|
||||||
wxLongLong m_nPausedPos;
|
wxLongLong m_nPausedPos;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxGStreamerMediaBackend);
|
DECLARE_DYNAMIC_CLASS(wxGStreamerMediaBackend);
|
||||||
@@ -150,15 +144,35 @@ public:
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxGStreamerMediaBackend, wxMediaBackend);
|
IMPLEMENT_DYNAMIC_CLASS(wxGStreamerMediaBackend, wxMediaBackend);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend Constructor
|
||||||
|
//
|
||||||
|
// Sets m_player to NULL signifying we havn't loaded anything yet
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
wxGStreamerMediaBackend::wxGStreamerMediaBackend() : m_player(NULL), m_videoSize(0,0)
|
wxGStreamerMediaBackend::wxGStreamerMediaBackend() : m_player(NULL), m_videoSize(0,0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend Destructor
|
||||||
|
//
|
||||||
|
// Stops/cleans up memory
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
wxGStreamerMediaBackend::~wxGStreamerMediaBackend()
|
wxGStreamerMediaBackend::~wxGStreamerMediaBackend()
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::OnGTKRealize
|
||||||
|
//
|
||||||
|
// If the window wasn't realized when Load was called, this is the
|
||||||
|
// callback for when it is.
|
||||||
|
//
|
||||||
|
// 1) Installs GTK idle handler if it doesn't exist
|
||||||
|
// 2) Yeilds to avoid an X11 bug (?)
|
||||||
|
// 3) Tells GStreamer to play the video in our control
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
@@ -184,7 +198,7 @@ gint wxGStreamerMediaBackend::OnGTKRealize(GtkWidget* theWidget,
|
|||||||
if (g_isIdle)
|
if (g_isIdle)
|
||||||
wxapp_install_idle_handler();
|
wxapp_install_idle_handler();
|
||||||
|
|
||||||
wxYield(); //X Server gets an error if I don't do this or a messagebox beforehand?!?!??
|
wxYield(); //FIXME: X Server gets an error if I don't do this or a messagebox beforehand?!?!??
|
||||||
|
|
||||||
GdkWindow *window = GTK_PIZZA(theWidget)->bin_window;
|
GdkWindow *window = GTK_PIZZA(theWidget)->bin_window;
|
||||||
wxASSERT(window);
|
wxASSERT(window);
|
||||||
@@ -199,20 +213,32 @@ gint wxGStreamerMediaBackend::OnGTKRealize(GtkWidget* theWidget,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Cleanup
|
||||||
|
//
|
||||||
|
// Frees the gstreamer interfaces if there were any created
|
||||||
|
//TODO: Do we need to free the video interface? I'm getting segfaults
|
||||||
|
//if I do...
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::Cleanup()
|
void wxGStreamerMediaBackend::Cleanup()
|
||||||
{
|
{
|
||||||
if(m_player && GST_IS_OBJECT(m_player))
|
if(m_player && GST_IS_OBJECT(m_player))
|
||||||
{
|
{
|
||||||
// wxASSERT(GST_IS_OBJECT(m_audiosink));
|
|
||||||
// wxASSERT(GST_IS_OBJECT(m_videosink));
|
|
||||||
|
|
||||||
gst_element_set_state (m_player, GST_STATE_NULL);
|
gst_element_set_state (m_player, GST_STATE_NULL);
|
||||||
gst_object_unref (GST_OBJECT (m_player));
|
gst_object_unref (GST_OBJECT (m_player));
|
||||||
//gst_object_unref (GST_OBJECT (m_videosink));
|
|
||||||
//gst_object_unref (GST_OBJECT (m_audiosink));
|
//if(GST_IS_OBJECT(m_videosink))
|
||||||
|
// gst_object_unref (GST_OBJECT (m_videosink));
|
||||||
|
//if(GST_IS_OBJECT(m_audiosink))
|
||||||
|
// gst_object_unref (GST_OBJECT (m_audiosink));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::CreateControl
|
||||||
|
//
|
||||||
|
// Initializes GStreamer and creates the wx side of our media control
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
||||||
wxWindowID id,
|
wxWindowID id,
|
||||||
const wxPoint& pos,
|
const wxPoint& pos,
|
||||||
@@ -231,6 +257,11 @@ bool wxGStreamerMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
|
|||||||
validator, name);
|
validator, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::TransCapsToVideoSize
|
||||||
|
//
|
||||||
|
// Gets the size of our video (in wxSize) from a GstPad
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::TransCapsToVideoSize(wxGStreamerMediaBackend* be, GstPad* pad)
|
bool wxGStreamerMediaBackend::TransCapsToVideoSize(wxGStreamerMediaBackend* be, GstPad* pad)
|
||||||
{
|
{
|
||||||
const GstCaps* caps = GST_PAD_CAPS (pad);
|
const GstCaps* caps = GST_PAD_CAPS (pad);
|
||||||
@@ -266,8 +297,12 @@ bool wxGStreamerMediaBackend::TransCapsToVideoSize(wxGStreamerMediaBackend* be,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//forces parent to recalc its layout if it has sizers to update
|
//---------------------------------------------------------------------------
|
||||||
//to the new video size
|
// wxGStreamerMediaBackend::PostRecalcSize
|
||||||
|
//
|
||||||
|
// Forces parent to recalc its layout if it has sizers to update
|
||||||
|
// to the new video size
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::PostRecalcSize()
|
void wxGStreamerMediaBackend::PostRecalcSize()
|
||||||
{
|
{
|
||||||
m_ctrl->InvalidateBestSize();
|
m_ctrl->InvalidateBestSize();
|
||||||
@@ -276,6 +311,16 @@ void wxGStreamerMediaBackend::PostRecalcSize()
|
|||||||
m_ctrl->GetParent()->Update();
|
m_ctrl->GetParent()->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::OnFinish
|
||||||
|
//
|
||||||
|
// Called by gstreamer when the media is done playing
|
||||||
|
//
|
||||||
|
// 1) Send a wxEVT_MEDIA_STOP to the control
|
||||||
|
// 2) If veteod, break out
|
||||||
|
// 3) really stop the media
|
||||||
|
// 4) Send a wxEVT_MEDIA_FINISHED to the control
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::OnFinish(GstElement *play, gpointer data)
|
void wxGStreamerMediaBackend::OnFinish(GstElement *play, gpointer data)
|
||||||
{
|
{
|
||||||
wxGStreamerMediaBackend* m_parent = (wxGStreamerMediaBackend*) data;
|
wxGStreamerMediaBackend* m_parent = (wxGStreamerMediaBackend*) data;
|
||||||
@@ -296,6 +341,13 @@ void wxGStreamerMediaBackend::OnFinish(GstElement *play, gpointer data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::OnError
|
||||||
|
//
|
||||||
|
// Called by gstreamer when an error is encountered playing the media
|
||||||
|
//
|
||||||
|
// TODO: Make this better - maybe some more intelligent wxLog stuff
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::OnError(GstElement *play,
|
void wxGStreamerMediaBackend::OnError(GstElement *play,
|
||||||
GstElement *src,
|
GstElement *src,
|
||||||
GError *err,
|
GError *err,
|
||||||
@@ -306,6 +358,11 @@ void wxGStreamerMediaBackend::OnError(GstElement *play,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Load (File version)
|
||||||
|
//
|
||||||
|
// Just calls the URI version
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::Load(const wxString& fileName)
|
bool wxGStreamerMediaBackend::Load(const wxString& fileName)
|
||||||
{
|
{
|
||||||
return Load(
|
return Load(
|
||||||
@@ -315,52 +372,76 @@ bool wxGStreamerMediaBackend::Load(const wxString& fileName)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::OnVideoCapsReady
|
||||||
|
//
|
||||||
|
// Called by gstreamer when the video caps for the media is ready
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::OnVideoCapsReady(GstPad* pad, GParamSpec* pspec, gpointer data)
|
void wxGStreamerMediaBackend::OnVideoCapsReady(GstPad* pad, GParamSpec* pspec, gpointer data)
|
||||||
{
|
{
|
||||||
wxGStreamerMediaBackend::TransCapsToVideoSize((wxGStreamerMediaBackend*) data, pad);
|
wxGStreamerMediaBackend::TransCapsToVideoSize((wxGStreamerMediaBackend*) data, pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Load (URI version)
|
||||||
|
//
|
||||||
|
// 1) Stops/Cleanups the previous instance if there is any
|
||||||
|
// 2) Creates the gstreamer interfaces - playbin and xvimagesink for video
|
||||||
|
// 3) If there is no playbin or video sink it bails out
|
||||||
|
// 4) Sets the playbin to have our video sink so we can set the window later
|
||||||
|
// 5) Set up the error and end-of-stream callbacks for our player
|
||||||
|
// 6) Make sure our video sink can support the x overlay interface
|
||||||
|
// 7) Make sure the passed URI is valid and tell playbin to load it
|
||||||
|
// 8) Use the xoverlay extension to tell gstreamer to play in our window
|
||||||
|
// 9) Get the video size - pause required to set the stream in action
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::Load(const wxURI& location)
|
bool wxGStreamerMediaBackend::Load(const wxURI& location)
|
||||||
{
|
{
|
||||||
|
//1
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
|
//2
|
||||||
m_player = gst_element_factory_make ("playbin", "play");
|
m_player = gst_element_factory_make ("playbin", "play");
|
||||||
m_audiosink = gst_element_factory_make ("alsasink", "audiosink");
|
// m_audiosink = gst_element_factory_make ("alsasink", "audiosink");
|
||||||
m_videosink = gst_element_factory_make ("xvimagesink", "videosink");
|
m_videosink = gst_element_factory_make ("xvimagesink", "videosink");
|
||||||
|
|
||||||
|
//3
|
||||||
//no playbin -- outta here :)
|
//no playbin -- outta here :)
|
||||||
if (!m_player)
|
if (!m_player || !GST_IS_OBJECT(m_videosink))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//have alsa?
|
// //have alsa?
|
||||||
if (GST_IS_OBJECT(m_audiosink) == false)
|
// if (GST_IS_OBJECT(m_audiosink) == false)
|
||||||
{
|
// {
|
||||||
//nope, try OSS
|
// //nope, try OSS
|
||||||
m_audiosink = gst_element_factory_make ("osssink", "audiosink");
|
// m_audiosink = gst_element_factory_make ("osssink", "audiosink");
|
||||||
wxASSERT_MSG(GST_IS_OBJECT(m_audiosink), wxT("WARNING: Alsa and OSS drivers for gstreamer not found - audio will be unavailable for wxMediaCtrl"));
|
// wxASSERT_MSG(GST_IS_OBJECT(m_audiosink), wxT("WARNING: Alsa and OSS drivers for gstreamer not found - audio will be unavailable for wxMediaCtrl"));
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
wxASSERT_MSG(GST_IS_OBJECT(m_videosink), wxT("WARNING: No X video driver for gstreamer not found - video will be unavailable for wxMediaCtrl"));
|
//4
|
||||||
|
|
||||||
g_object_set (G_OBJECT (m_player),
|
g_object_set (G_OBJECT (m_player),
|
||||||
"video-sink", m_videosink,
|
"video-sink", m_videosink,
|
||||||
"audio-sink", m_audiosink,
|
// "audio-sink", m_audiosink,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
//5
|
||||||
g_signal_connect (m_player, "eos", G_CALLBACK (OnError), this);
|
g_signal_connect (m_player, "eos", G_CALLBACK (OnError), this);
|
||||||
g_signal_connect (m_player, "error", G_CALLBACK (OnFinish), this);
|
g_signal_connect (m_player, "error", G_CALLBACK (OnFinish), this);
|
||||||
|
|
||||||
|
//6
|
||||||
wxASSERT( GST_IS_X_OVERLAY(m_videosink) );
|
wxASSERT( GST_IS_X_OVERLAY(m_videosink) );
|
||||||
if ( ! GST_IS_X_OVERLAY(m_videosink) )
|
if ( ! GST_IS_X_OVERLAY(m_videosink) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//7
|
||||||
wxString locstring = location.BuildUnescapedURI();
|
wxString locstring = location.BuildUnescapedURI();
|
||||||
wxASSERT(gst_uri_protocol_is_valid("file"));
|
wxASSERT(gst_uri_protocol_is_valid("file"));
|
||||||
wxASSERT(gst_uri_is_valid(locstring.mb_str()));
|
wxASSERT(gst_uri_is_valid(locstring.mb_str()));
|
||||||
|
|
||||||
g_object_set (G_OBJECT (m_player), "uri", (const char*)locstring.mb_str(), NULL);
|
g_object_set (G_OBJECT (m_player), "uri", (const char*)locstring.mb_str(), NULL);
|
||||||
|
|
||||||
|
//8
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
if(!GTK_WIDGET_REALIZED(m_ctrl->m_wxwindow))
|
if(!GTK_WIDGET_REALIZED(m_ctrl->m_wxwindow))
|
||||||
{
|
{
|
||||||
@@ -390,6 +471,7 @@ bool wxGStreamerMediaBackend::Load(const wxURI& location)
|
|||||||
} //end else block
|
} //end else block
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//9
|
||||||
wxASSERT(gst_element_set_state (m_player,
|
wxASSERT(gst_element_set_state (m_player,
|
||||||
GST_STATE_PAUSED) == GST_STATE_SUCCESS);
|
GST_STATE_PAUSED) == GST_STATE_SUCCESS);
|
||||||
|
|
||||||
@@ -445,6 +527,11 @@ bool wxGStreamerMediaBackend::Load(const wxURI& location)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Play
|
||||||
|
//
|
||||||
|
// Sets the stream to a playing state
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::Play()
|
bool wxGStreamerMediaBackend::Play()
|
||||||
{
|
{
|
||||||
if (gst_element_set_state (m_player, GST_STATE_PLAYING)
|
if (gst_element_set_state (m_player, GST_STATE_PLAYING)
|
||||||
@@ -453,6 +540,11 @@ bool wxGStreamerMediaBackend::Play()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Pause
|
||||||
|
//
|
||||||
|
// Marks where we paused and pauses the stream
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::Pause()
|
bool wxGStreamerMediaBackend::Pause()
|
||||||
{
|
{
|
||||||
m_nPausedPos = GetPosition();
|
m_nPausedPos = GetPosition();
|
||||||
@@ -462,6 +554,11 @@ bool wxGStreamerMediaBackend::Pause()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Stop
|
||||||
|
//
|
||||||
|
// Pauses the stream and sets the position to 0
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
bool wxGStreamerMediaBackend::Stop()
|
bool wxGStreamerMediaBackend::Stop()
|
||||||
{
|
{
|
||||||
if (gst_element_set_state (m_player,
|
if (gst_element_set_state (m_player,
|
||||||
@@ -470,6 +567,11 @@ bool wxGStreamerMediaBackend::Stop()
|
|||||||
return wxGStreamerMediaBackend::SetPosition(0);
|
return wxGStreamerMediaBackend::SetPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::GetState
|
||||||
|
//
|
||||||
|
// Gets the state of the stream
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
wxMediaState wxGStreamerMediaBackend::GetState()
|
wxMediaState wxGStreamerMediaBackend::GetState()
|
||||||
{
|
{
|
||||||
switch(GST_STATE(m_player))
|
switch(GST_STATE(m_player))
|
||||||
@@ -486,21 +588,19 @@ wxMediaState wxGStreamerMediaBackend::GetState()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGStreamerMediaBackend::SetPosition(wxLongLong where)
|
//---------------------------------------------------------------------------
|
||||||
{
|
// wxGStreamerMediaBackend::GetPosition
|
||||||
if( gst_element_seek (m_player, (GstSeekType) (GST_SEEK_METHOD_SET |
|
//
|
||||||
GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH),
|
// If paused, returns our marked position - otherwise it queries the
|
||||||
where.GetValue() * GST_MSECOND ) )
|
// GStreamer playbin for the position and returns that
|
||||||
{
|
//
|
||||||
if (GetState() != wxMEDIASTATE_PLAYING)
|
//TODO:
|
||||||
m_nPausedPos = where;
|
//TODO: In lue of the last big TODO, when you pause and seek gstreamer
|
||||||
|
//TODO: doesn't update the position sometimes, so we need to keep track of whether
|
||||||
return true;
|
//TODO: we have paused or not and keep track of the time after the pause
|
||||||
}
|
//TODO: and whenever the user seeks while paused
|
||||||
|
//TODO:
|
||||||
return false;
|
//---------------------------------------------------------------------------
|
||||||
}
|
|
||||||
|
|
||||||
wxLongLong wxGStreamerMediaBackend::GetPosition()
|
wxLongLong wxGStreamerMediaBackend::GetPosition()
|
||||||
{
|
{
|
||||||
if(GetState() != wxMEDIASTATE_PLAYING)
|
if(GetState() != wxMEDIASTATE_PLAYING)
|
||||||
@@ -516,6 +616,35 @@ wxLongLong wxGStreamerMediaBackend::GetPosition()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::SetPosition
|
||||||
|
//
|
||||||
|
// Sets the position of the stream
|
||||||
|
// Note that GST_MSECOND is 1000000 (GStreamer uses nanoseconds - so
|
||||||
|
// there is 1000000 nanoseconds in a millisecond)
|
||||||
|
//
|
||||||
|
// If paused marks where we seeked to
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
bool wxGStreamerMediaBackend::SetPosition(wxLongLong where)
|
||||||
|
{
|
||||||
|
if( gst_element_seek (m_player, (GstSeekType) (GST_SEEK_METHOD_SET |
|
||||||
|
GST_FORMAT_TIME | GST_SEEK_FLAG_FLUSH),
|
||||||
|
where.GetValue() * GST_MSECOND ) )
|
||||||
|
{
|
||||||
|
if (GetState() != wxMEDIASTATE_PLAYING)
|
||||||
|
m_nPausedPos = where;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::GetDuration
|
||||||
|
//
|
||||||
|
// Obtains the total time of our stream
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
wxLongLong wxGStreamerMediaBackend::GetDuration()
|
wxLongLong wxGStreamerMediaBackend::GetDuration()
|
||||||
{
|
{
|
||||||
gint64 length;
|
gint64 length;
|
||||||
@@ -526,31 +655,46 @@ wxLongLong wxGStreamerMediaBackend::GetDuration()
|
|||||||
return length / GST_MSECOND ;
|
return length / GST_MSECOND ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::Move
|
||||||
|
//
|
||||||
|
// Called when the window is moved - GStreamer takes care of this
|
||||||
|
// for us so nothing is needed
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void wxGStreamerMediaBackend::Move(int x, int y, int w, int h)
|
void wxGStreamerMediaBackend::Move(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::GetVideoSize
|
||||||
|
//
|
||||||
|
// Returns our cached video size from Load/OnVideoCapsReady
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
wxSize wxGStreamerMediaBackend::GetVideoSize() const
|
wxSize wxGStreamerMediaBackend::GetVideoSize() const
|
||||||
{
|
{
|
||||||
return m_videoSize;
|
return m_videoSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// wxGStreamerMediaBackend::GetPlaybackRate
|
||||||
|
// wxGStreamerMediaBackend::SetPlaybackRate
|
||||||
//
|
//
|
||||||
//PlaybackRate not currently supported via playbin directly -
|
// Obtains/Sets the playback rate of the stream
|
||||||
// Ronald S. Bultje noted on gstreamer-devel:
|
|
||||||
//
|
//
|
||||||
// Like "play at twice normal speed"? Or "play at 25 fps and 44,1 kHz"? As
|
//TODO: PlaybackRate not currently supported via playbin directly -
|
||||||
// for the first, yes, we have elements for that, btu they"re not part of
|
//TODO: Ronald S. Bultje noted on gstreamer-devel:
|
||||||
// playbin. You can create a bin (with a ghost pad) containing the actual
|
//TODO:
|
||||||
// video/audiosink and the speed-changing element for this, and set that
|
//TODO: Like "play at twice normal speed"? Or "play at 25 fps and 44,1 kHz"? As
|
||||||
// element as video-sink or audio-sink property in playbin. The
|
//TODO: for the first, yes, we have elements for that, btu they"re not part of
|
||||||
// audio-element is called "speed", the video-element is called "videodrop"
|
//TODO: playbin. You can create a bin (with a ghost pad) containing the actual
|
||||||
// (although that appears to be deprecated in favour of "videorate", which
|
//TODO: video/audiosink and the speed-changing element for this, and set that
|
||||||
// again cannot do this, so this may not work at all in the end). For
|
//TODO: element as video-sink or audio-sink property in playbin. The
|
||||||
// forcing frame/samplerates, see audioscale and videorate. Audioscale is
|
//TODO: audio-element is called "speed", the video-element is called "videodrop"
|
||||||
// part of playbin.
|
//TODO: (although that appears to be deprecated in favour of "videorate", which
|
||||||
//
|
//TODO: again cannot do this, so this may not work at all in the end). For
|
||||||
|
//TODO: forcing frame/samplerates, see audioscale and videorate. Audioscale is
|
||||||
|
//TODO: part of playbin.
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
double wxGStreamerMediaBackend::GetPlaybackRate()
|
double wxGStreamerMediaBackend::GetPlaybackRate()
|
||||||
{
|
{
|
||||||
//not currently supported via playbin
|
//not currently supported via playbin
|
||||||
|
Reference in New Issue
Block a user