[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/asobj/NetStreamGst.cpp s...
From: |
Tomas Groth |
Subject: |
[Gnash-commit] gnash ChangeLog server/asobj/NetStreamGst.cpp s... |
Date: |
Wed, 16 May 2007 16:08:13 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Tomas Groth <tgc> 07/05/16 16:08:12
Modified files:
. : ChangeLog
server/asobj : NetStreamGst.cpp NetStreamGst.h
Log message:
* server/asobj/NetStreamGst.{cpp,h}: Split startPlayback() into
smaller function (buildFLVPipeline and buildPipeline). Made
sure
gstreamer elements are cleaned up if setup fails
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.3239&r2=1.3240
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.cpp?cvsroot=gnash&r1=1.41&r2=1.42
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.h?cvsroot=gnash&r1=1.19&r2=1.20
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.3239
retrieving revision 1.3240
diff -u -b -r1.3239 -r1.3240
--- ChangeLog 16 May 2007 15:58:22 -0000 1.3239
+++ ChangeLog 16 May 2007 16:08:12 -0000 1.3240
@@ -1,3 +1,9 @@
+2007-05-16 Tomas Groth Christensen <address@hidden>
+
+ * server/asobj/NetStreamGst.{cpp,h}: Split startPlayback() into
+ smaller function (buildFLVPipeline and buildPipeline). Made sure
+ gstreamer elements are cleaned up if setup fails.
+
2007-05-16 Rob Savoye <address@hidden>
* configure.ac: Eval lists so the embedded variables get
Index: server/asobj/NetStreamGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -b -r1.41 -r1.42
--- server/asobj/NetStreamGst.cpp 16 May 2007 13:01:02 -0000 1.41
+++ server/asobj/NetStreamGst.cpp 16 May 2007 16:08:12 -0000 1.42
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: NetStreamGst.cpp,v 1.41 2007/05/16 13:01:02 strk Exp $ */
+/* $Id: NetStreamGst.cpp,v 1.42 2007/05/16 16:08:12 tgc Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -148,6 +148,7 @@
}
// Should we keep the ref if the above failed ?
+ // Unreffing the pipeline should also unref all elements in it.
gst_object_unref (GST_OBJECT (pipeline));
if (m_imageframe) delete m_imageframe;
@@ -352,142 +353,74 @@
}
void
-NetStreamGst::startPlayback()
+NetStreamGst::unrefElements()
{
- NetStreamGst* ns = this; // quick hack
-
- boost::intrusive_ptr<NetConnection> nc = ns->_netCon;
- assert(nc);
-
- // Pass stuff from/to the NetConnection object.
- assert(ns);
- if ( !nc->openConnection(ns->url) ) {
- ns->setStatus(streamNotFound);
- log_debug(_("Gnash could not open movie: %s"), ns->url.c_str());
- return;
- }
-
- ns->inputPos = 0;
-
- uint8_t head[3];
- if (nc->read(head, 3) < 3) {
- ns->setStatus(streamNotFound);
- return;
- }
- nc->seek(0);
- if (head[0] == 'F' && head[1] == 'L' && head[2] == 'V') {
- ns->m_isFLV = true;
- ns->m_parser = new FLVParser(); // TODO: define ownership, use
auto_ptr !
- if (!nc->connectParser(*(ns->m_parser))) {
- ns->setStatus(streamNotFound);
- log_debug(_("Gnash could not open movie: %s"),
ns->url.c_str());
- return;
-
- }
- }
-
- // setup the GnashNC plugin if we are not decoding FLV
- if (!ns->m_isFLV) _gst_plugin_register_static (&gnash_plugin_desc);
-
- // setup the pipeline
- ns->pipeline = gst_pipeline_new (NULL);
-
- // Check if the creation of the gstreamer pipeline was a succes
- if (!ns->pipeline) {
- gnash::log_error(_("The gstreamer pipeline element could not be
created"));
- return;
- }
-
- bool video = false;
- bool sound = false;
+log_debug("unreffing elements");
+ gst_object_unref (GST_OBJECT (pipeline));
+ gst_object_unref (GST_OBJECT (audiosink));
+ gst_object_unref (GST_OBJECT (videosink));
- // If sound is enabled we set it up
- if (get_sound_handler()) sound = true;
+ gst_object_unref (GST_OBJECT (volume));
+ gst_object_unref (GST_OBJECT (colorspace));
+ gst_object_unref (GST_OBJECT (videorate));
+ gst_object_unref (GST_OBJECT (videocaps));
+ gst_object_unref (GST_OBJECT (videoflip));
+ gst_object_unref (GST_OBJECT (audioconv));
- if (sound) {
- // create an audio sink - use oss, alsa or...? make a
commandline option?
- // we first try autodetect, then alsa, then oss, then esd,
then...?
- // If the gstreamer adder ever gets fixed this should be
connected to the
- // adder in the soundhandler.
-#if !defined(__NetBSD__)
- ns->audiosink = gst_element_factory_make ("autoaudiosink",
NULL);
- if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("alsasink", NULL);
- if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("osssink", NULL);
-#endif
- if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("esdsink", NULL);
+ if (m_isFLV) {
+ gst_object_unref (GST_OBJECT (audiosource));
+ gst_object_unref (GST_OBJECT (videosource));
+ gst_object_unref (GST_OBJECT (videodecoder));
+ gst_object_unref (GST_OBJECT (audiodecoder));
+ gst_object_unref (GST_OBJECT (videoinputcaps));
+ gst_object_unref (GST_OBJECT (audioinputcaps));
- if (!ns->audiosink) {
- log_error(_("The gstreamer audiosink element could not
be created"));
- return;
- }
- // setup the audio converter
- ns->audioconv = gst_element_factory_make ("audioconvert", NULL);
- if (!ns->audioconv) {
- log_error(_("The gstreamer audioconvert element could
not be created"));
- return;
- }
+ } else {
+ gst_object_unref (GST_OBJECT (source));
+ gst_object_unref (GST_OBJECT (decoder));
- // setup the volume controller
- ns->volume = gst_element_factory_make ("volume", NULL);
- if (!ns->volume) {
- log_error(_("The gstreamer volume element could not be
created"));
- return;
}
+}
- } else {
- ns->audiosink = gst_element_factory_make ("fakesink", NULL);
- if (!ns->audiosink) {
- log_error(_("The gstreamer fakesink element could not
be created"));
- // TODO: what to do in these cases ?
- return;
- }
- }
- // setup gnashnc source if we are not decoding FLV (our homegrown
source element)
- if (!ns->m_isFLV) {
- ns->source = gst_element_factory_make ("gnashsrc", NULL);
- if ( ! ns->source )
- {
- log_error("Failed to create 'gnashrc' element");
- // TODO: should we still create the gnashrc_callback
below ?
- }
- gnashsrc_callback* gc = new gnashsrc_callback; // TODO: who's
going to delete this ?
- gc->read = NetStreamGst::readPacket;
- gc->seek = NetStreamGst::seekMedia;
- g_object_set (G_OBJECT (ns->source), "data", ns, "callbacks",
gc, NULL);
- } else {
+bool
+NetStreamGst::buildFLVPipeline(bool* sound, bool* video)
+{
+ log_debug("Building FLV decoding pipeline");
+ FLVVideoInfo* videoInfo = m_parser->getVideoInfo();
- FLVVideoInfo* videoInfo = ns->m_parser->getVideoInfo();
+ bool doVideo = *video;
+ bool doSound = *sound;
if (videoInfo) {
- video = true;
- ns->videosource = gst_element_factory_make ("fakesrc",
NULL);
- if ( ! ns->videosource )
+ doVideo = true;
+ videosource = gst_element_factory_make ("fakesrc", NULL);
+ if ( ! videosource )
{
log_error("Unable to create videosource
'fakesrc' element");
- // TODO: what to do in this case ?
+ return false;
}
// setup fake source
- g_object_set (G_OBJECT (ns->videosource),
+ g_object_set (G_OBJECT (videosource),
"sizetype", 2,
"can-activate-pull", FALSE, "signal-handoffs", TRUE, NULL);
// Setup the callback
if ( ! connectVideoHandoffSignal() )
{
log_error("Unable to connect the video
'handoff' signal handler");
- // TODO: what to do in this case ?
+ return false;
}
// Setup the input capsfilter
- ns->videoinputcaps = gst_element_factory_make
("capsfilter", NULL);
- if ( ! ns->videoinputcaps )
+ videoinputcaps = gst_element_factory_make ("capsfilter", NULL);
+ if ( ! videoinputcaps )
{
log_error("Unable to create videoinputcaps
'capsfilter' element");
- // TODO: what to do in this case ?
+ return false;
}
- uint32_t fps = ns->m_parser->videoFrameRate();
+ uint32_t fps = m_parser->videoFrameRate();
GstCaps* videonincaps;
if (videoInfo->codec == VIDEO_CODEC_H263) {
@@ -497,17 +430,17 @@
"framerate", GST_TYPE_FRACTION, fps, 1,
"flvversion", G_TYPE_INT, 1,
NULL);
- ns->videodecoder = gst_element_factory_make
("ffdec_flv", NULL);
- if ( ! ns->videodecoder )
+ videodecoder = gst_element_factory_make ("ffdec_flv",
NULL);
+ if ( ! videodecoder )
{
log_error("Unable to create
videodecoder 'ffdec_flv' element");
- // TODO: what to do in this case ?
+ return false;
}
// Check if the element was correctly created
- if (!ns->videodecoder) {
+ if (!videodecoder) {
log_error(_("A gstreamer flashvideo
(h.263) decoder element could not be created. You probably need to install
gst-ffmpeg."));
- return;
+ return false;
}
} else if (videoInfo->codec == VIDEO_CODEC_VP6) {
@@ -516,17 +449,17 @@
"height", G_TYPE_INT, 240,
"framerate", GST_TYPE_FRACTION, fps, 1,
NULL);
- ns->videodecoder = gst_element_factory_make
("ffdec_vp6f", NULL);
- if ( ! ns->videodecoder )
+ videodecoder = gst_element_factory_make ("ffdec_vp6f",
NULL);
+ if ( ! videodecoder )
{
log_error("Unable to create
videodecoder 'ffdec_vp6f' element");
- // TODO: what to do in this case ?
+ return false;
}
// Check if the element was correctly created
- if (!ns->videodecoder) {
+ if (!videodecoder) {
log_error(_("A gstreamer flashvideo
(VP6) decoder element could not be created! You probably need to install
gst-ffmpeg."));
- return;
+ return false;
}
} else if (videoInfo->codec == VIDEO_CODEC_SCREENVIDEO)
{
@@ -535,37 +468,37 @@
"height", G_TYPE_INT, 240,
"framerate", GST_TYPE_FRACTION, fps, 1,
NULL);
- ns->videodecoder = gst_element_factory_make
("ffdec_flashsv", NULL);
+ videodecoder = gst_element_factory_make
("ffdec_flashsv", NULL);
// Check if the element was correctly created
- if (!ns->videodecoder) {
+ if (!videodecoder) {
log_error(_("A gstreamer flashvideo
(ScreenVideo) decoder element could not be created! You probably need to
install gst-ffmpeg."));
- return;
+ return false;
}
} else {
- log_error(_("Unsupported video codec %d"),
- videoInfo->codec);
- return;
+ log_error(_("Unsupported video codec %d"),
videoInfo->codec);
+ return false;
}
- g_object_set (G_OBJECT (ns->videoinputcaps), "caps",
videonincaps, NULL);
+ g_object_set (G_OBJECT (videoinputcaps), "caps", videonincaps,
NULL);
gst_caps_unref (videonincaps);
}
- FLVAudioInfo* audioInfo = ns->m_parser->getAudioInfo();
- if (!audioInfo) sound = false;
+ FLVAudioInfo* audioInfo = m_parser->getAudioInfo();
+ if (!audioInfo) doSound = false;
- if (sound) {
- ns->audiosource = gst_element_factory_make ("fakesrc",
NULL);
- if ( ! ns->audiosource )
+ if (doSound) {
+ audiosource = gst_element_factory_make ("fakesrc", NULL);
+ if ( ! audiosource )
{
log_error("Unable to create audiosource
'fakesrc' element");
+ return false;
}
// setup fake source
- g_object_set (G_OBJECT (ns->audiosource),
+ g_object_set (G_OBJECT (audiosource),
"sizetype", 2,
"can-activate-pull", FALSE, "signal-handoffs", TRUE, NULL);
// Setup the callback
@@ -578,26 +511,25 @@
if (audioInfo->codec == AUDIO_CODEC_MP3) {
- ns->audiodecoder = gst_element_factory_make
("mad", NULL);
- if ( ! ns->audiodecoder )
+ audiodecoder = gst_element_factory_make ("mad", NULL);
+ if ( ! audiodecoder )
{
- ns->audiodecoder =
gst_element_factory_make ("flump3dec", NULL);
+ audiodecoder = gst_element_factory_make
("flump3dec", NULL);
// Check if the element was correctly
created
- if (!ns->audiodecoder)
+ if (!audiodecoder)
{
log_error(_("A gstreamer
mp3-decoder element could not be created! You probably need to install a
mp3-decoder plugin like gstreamer0.10-mad or gstreamer0.10-fluendo-mp3."));
- return;
+ return false;
}
}
-
// Set the info about the stream so that
gstreamer knows what it is.
- ns->audioinputcaps = gst_element_factory_make
("capsfilter", NULL);
- if (!ns->audioinputcaps)
+ audioinputcaps = gst_element_factory_make
("capsfilter", NULL);
+ if (!audioinputcaps)
{
log_error("Unable to create
audioinputcaps 'capsfilter' element");
- // TODO: what to do in this case ?
+ return false;
}
GstCaps* audioincaps = gst_caps_new_simple
("audio/mpeg",
@@ -605,25 +537,157 @@
"layer", G_TYPE_INT, 3,
"rate", G_TYPE_INT,
audioInfo->sampleRate,
"channels", G_TYPE_INT,
audioInfo->stereo ? 2 : 1, NULL);
- g_object_set (G_OBJECT (ns->audioinputcaps),
"caps", audioincaps, NULL);
+ g_object_set (G_OBJECT (audioinputcaps), "caps",
audioincaps, NULL);
gst_caps_unref (audioincaps);
} else {
- log_error(_("Unsupported audio codec %d"),
- audioInfo->codec);
- return;
+ log_error(_("Unsupported audio codec %d"),
audioInfo->codec);
+ return false;
}
}
+
+ *sound = doSound;
+ *video = doVideo;
+
+ return true;
+}
+
+bool
+NetStreamGst::buildPipeline()
+{
+ log_debug("Building non-FLV decoding pipeline");
+
+ // setup gnashnc source if we are not decoding FLV (our homegrown
source element)
+ source = gst_element_factory_make ("gnashsrc", NULL);
+ if ( ! source )
+ {
+ log_error("Failed to create 'gnashrc' element");
+ return false;
}
+ gnashsrc_callback* gc = new gnashsrc_callback; // TODO: who's going to
delete this ?
+ gc->read = NetStreamGst::readPacket;
+ gc->seek = NetStreamGst::seekMedia;
+ g_object_set (G_OBJECT (source), "data", this, "callbacks", gc, NULL);
- // setup the decoder with callback, but only if we are not decoding a
FLV
- if (!ns->m_isFLV) {
- ns->decoder = gst_element_factory_make ("decodebin", NULL);
- if (!ns->decoder)
+ // setup the decoder with callback
+ decoder = gst_element_factory_make ("decodebin", NULL);
+ if (!decoder)
{
log_error("Unable to create decoder 'decodebin'
element");
- // TODO: what to do in this case ?
+ return false;
+ }
+ g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK
(NetStreamGst::callback_newpad), this);
+
+ return true;
+}
+
+
+void
+NetStreamGst::startPlayback()
+{
+ NetStreamGst* ns = this; // quick hack
+
+ boost::intrusive_ptr<NetConnection> nc = ns->_netCon;
+ assert(nc);
+
+ // Pass stuff from/to the NetConnection object.
+ assert(ns);
+ if ( !nc->openConnection(ns->url) ) {
+ ns->setStatus(streamNotFound);
+ log_debug(_("Gnash could not open movie: %s"), ns->url.c_str());
+ return;
+ }
+
+ ns->inputPos = 0;
+
+ uint8_t head[3];
+ if (nc->read(head, 3) < 3) {
+ ns->setStatus(streamNotFound);
+ return;
+ }
+ nc->seek(0);
+ if (head[0] == 'F' && head[1] == 'L' && head[2] == 'V') {
+ ns->m_isFLV = true;
+ ns->m_parser = new FLVParser(); // TODO: define ownership, use
auto_ptr !
+ if (!nc->connectParser(*(ns->m_parser))) {
+ ns->setStatus(streamNotFound);
+ log_debug(_("Gnash could not open movie: %s"),
ns->url.c_str());
+ return;
+
+ }
+ }
+
+ // setup the GnashNC plugin if we are not decoding FLV
+ if (!ns->m_isFLV) _gst_plugin_register_static (&gnash_plugin_desc);
+
+ // setup the pipeline
+ ns->pipeline = gst_pipeline_new (NULL);
+
+ // Check if the creation of the gstreamer pipeline was a succes
+ if (!ns->pipeline) {
+ gnash::log_error(_("The gstreamer pipeline element could not be
created"));
+ return;
+ }
+
+ bool video = false;
+ bool sound = false;
+
+ // If sound is enabled we set it up
+ if (get_sound_handler()) sound = true;
+
+ // Setup the decoder and source
+ if (ns->m_isFLV) {
+ if (!buildFLVPipeline(&sound, &video)) {
+ unrefElements();
+ return;
+ }
+ } else {
+ if (!buildPipeline()) {
+ unrefElements();
+ return;
+ }
+ }
+
+
+ if (sound) {
+ // create an audio sink - use oss, alsa or...? make a
commandline option?
+ // we first try autodetect, then alsa, then oss, then esd,
then...?
+ // If the gstreamer adder ever gets fixed this should be
connected to the
+ // adder in the soundhandler.
+#if !defined(__NetBSD__)
+ ns->audiosink = gst_element_factory_make ("autoaudiosink",
NULL);
+ if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("alsasink", NULL);
+ if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("osssink", NULL);
+#endif
+ if (!ns->audiosink) ns->audiosink = gst_element_factory_make
("esdsink", NULL);
+
+ if (!ns->audiosink) {
+ log_error(_("The gstreamer audiosink element could not
be created"));
+ unrefElements();
+ return;
+ }
+ // setup the audio converter
+ ns->audioconv = gst_element_factory_make ("audioconvert", NULL);
+ if (!ns->audioconv) {
+ log_error(_("The gstreamer audioconvert element could
not be created"));
+ unrefElements();
+ return;
+ }
+
+ // setup the volume controller
+ ns->volume = gst_element_factory_make ("volume", NULL);
+ if (!ns->volume) {
+ log_error(_("The gstreamer volume element could not be
created"));
+ unrefElements();
+ return;
+ }
+
+ } else {
+ ns->audiosink = gst_element_factory_make ("fakesink", NULL);
+ if (!ns->audiosink) {
+ log_error(_("The gstreamer fakesink element could not
be created"));
+ unrefElements();
+ return;
}
- g_signal_connect (ns->decoder, "new-decoded-pad", G_CALLBACK
(NetStreamGst::callback_newpad), ns);
}
if (video) {
@@ -632,7 +696,8 @@
if (!ns->colorspace)
{
log_error("Unable to create colorspace
'ffmpegcolorspace' element");
- // TODO: what to do in this case ?
+ unrefElements();
+ return;
}
// Setup the capsfilter which demands either YUV or RGB
videoframe format
@@ -640,7 +705,8 @@
if (!ns->videocaps)
{
log_error("Unable to create videocaps 'capsfilter'
element");
- // TODO: what to do in this case ?
+ unrefElements();
+ return;
}
GstCaps* videooutcaps;
@@ -657,7 +723,8 @@
if (!ns->videorate)
{
log_error("Unable to create videorate 'videorate'
element");
- // TODO: what to do in this case ?
+ unrefElements();
+ return;
}
// setup the videosink with callback
@@ -665,7 +732,8 @@
if (!ns->videosink)
{
log_error("Unable to create videosink 'fakesink'
element");
- // TODO: what to do in this case ?
+ unrefElements();
+ return;
}
g_object_set (G_OBJECT (ns->videosink), "signal-handoffs",
TRUE, "sync", TRUE, NULL);
@@ -673,25 +741,9 @@
g_signal_connect (ns->videosink, "handoff", G_CALLBACK
(NetStreamGst::callback_output), ns);
}
- if (ns->m_isFLV) {
- if (video && (!ns->videosource || !ns->videoinputcaps)) {
- log_error(_("Gstreamer source element(s) for video
movie handling could not be created, you probably need to install
gstreamer0.10-core for fakesrc and capsfilter support."));
- return;
- }
- if (sound && (!ns->audiosource || !ns->audioinputcaps)) {
- log_error(_("Gstreamer source element(s) for audio
movie handling could not be created, you probably need to install
gstreamer0.10-core for fakesrc and capsfilter support."));
- return;
- }
-
- } else {
- if (!ns->decoder || !ns->source) {
- log_error(_("Gstreamer element(s) for movie handling
could not be created, you probably need to install gstreamer0.10-base for
decodebin support."));
- return;
- }
- }
-
if (video && (!ns->colorspace || !ns->videocaps || !ns->videorate ||
!ns->videosink)) {
log_error(_("Gstreamer element(s) for video movie handling
could not be created, you probably need to install gstreamer0.10-base for
ffmpegcolorspace and videorate support."));
+ unrefElements();
return;
}
@@ -810,14 +862,13 @@
log_error("Could not pause pipeline");
}
- /// TODO: shouldn't we check 'ret' value here !!??
-
int64_t pos;
GstState current, pending;
GstStateChangeReturn ret;
GstFormat fmt = GST_FORMAT_TIME;
ret = gst_element_get_state (GST_ELEMENT (pipeline),
¤t, &pending, 0);
+ if (ret == GST_STATE_CHANGE_SUCCESS) {
if (current != GST_STATE_NULL &&
gst_element_query_position (pipeline, &fmt, &pos)) {
pos = pos / 1000000;
} else {
@@ -825,6 +876,12 @@
}
// Buffer a second before continuing
m_bufferTime = pos + 1000;
+ } else {
+ // the pipeline failed state change
+ log_error("Pipeline failed to complete state
change!");
+
+ // @@ eh.. what to do then
+ }
}
}
Index: server/asobj/NetStreamGst.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/asobj/NetStreamGst.h 16 May 2007 12:50:26 -0000 1.19
+++ server/asobj/NetStreamGst.h 16 May 2007 16:08:12 -0000 1.20
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $id$ */
+/* $Id: */
#ifndef __NETSTREAMGST_H__
#define __NETSTREAMGST_H__
@@ -70,6 +70,21 @@
private:
+ /// Creates the decoders and source elements for playing FLVs
+ //
+ /// @return true on success, false on failure
+ ///
+ bool buildFLVPipeline(bool* sound, bool* video);
+
+ /// Creates the decoder and source element for playing non-FLVs
+ //
+ /// @return true on success, false on failure
+ ///
+ bool buildPipeline();
+
+ /// Unrefs (deletes) all the gstreamer elements. Used when the setup
failed.
+ void unrefElements();
+
/// Connect the video "handoff" signal
//
/// @return true on success, false on failure
@@ -158,6 +173,10 @@
int videowidth;
int videoheight;
+ // Used when seeking. To make the gst-pipeline more cooperative
+ // we don't tell it when we seek, but just add m_clock_offset to
+ // make it believe the search never happend. A better aproach whould
+ // probably be to make a dedicated gstreamer source element.
volatile long m_clock_offset;
// On next advance() should we pause?