[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog configure.ac backend/render_han...
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] gnash ChangeLog configure.ac backend/render_han... |
Date: |
Sun, 27 Jan 2008 07:18:21 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Bastiaan Jacques <bjacques> 08/01/27 07:18:20
Modified files:
. : ChangeLog configure.ac
backend : render_handler_ogl.cpp
libbase : image.cpp image.h
libmedia/gst : MediaDecoderGst.cpp VideoDecoderGst.cpp
VideoDecoderGst.h gstappsink.c gstappsink.h
gstappsrc.c
server/asobj : NetStream.cpp NetStream.h NetStreamGst.cpp
server/parser : video_stream_def.cpp video_stream_def.h
Log message:
* configure.ac: Add some required gstreamer modules to detect.
* libbase/image.cpp: Call the data() member function of the
"source"
image when update() is called.
* libbase/image.h: Make data() virtual. Add an explicit
constructor
for rgb similar to the one in image_base.
* libmedia/gst/MediaDecoderGst.cpp: Exclude some code relying
on old
VideoDecoderGst behaviour.
* libmedia/gst/VideoDecoderGst.{cpp,h}: Reimplement
VideoDecoderGst
with a simple push/pop interface. Add a class gnashGstBuffer
which
wraps the reference counted GstBuffer as a subclass of
image::rgb.
This fixes bug #22067.
* libmedia/gst/gstappsink.{c,h}: Statically load this gstreamer
module. Add a non-blocking method for peeking the queue.
* libmedia/gst/gstappsrc.c: Statically load the appsrc module.
* server/asobj/NetStream.{cpp,h}: Change the argument to seek()
from
milliseconds to seconds, because that's what is received from
ActionScript.
* server/asobj/NetStreamGst.cpp: Add a missing break in the
message
parsing switch.
* server/parser/video_stream_def.{cpp,h}: Use the new
VideoStreamGst
implementation.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5503&r2=1.5504
http://cvs.savannah.gnu.org/viewcvs/gnash/configure.ac?cvsroot=gnash&r1=1.476&r2=1.477
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/render_handler_ogl.cpp?cvsroot=gnash&r1=1.104&r2=1.105
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/image.cpp?cvsroot=gnash&r1=1.26&r2=1.27
http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/image.h?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/MediaDecoderGst.cpp?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/gstappsink.c?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/gstappsink.h?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/gstappsrc.c?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.cpp?cvsroot=gnash&r1=1.83&r2=1.84
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.h?cvsroot=gnash&r1=1.57&r2=1.58
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.cpp?cvsroot=gnash&r1=1.74&r2=1.75
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.h?cvsroot=gnash&r1=1.21&r2=1.22
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5503
retrieving revision 1.5504
diff -u -b -r1.5503 -r1.5504
--- ChangeLog 26 Jan 2008 12:31:10 -0000 1.5503
+++ ChangeLog 27 Jan 2008 07:18:15 -0000 1.5504
@@ -1,3 +1,27 @@
+2008-01-26 Bastiaan Jacques <address@hidden>
+
+ * configure.ac: Add some required gstreamer modules to detect.
+ * libbase/image.cpp: Call the data() member function of the "source"
+ image when update() is called.
+ * libbase/image.h: Make data() virtual. Add an explicit constructor
+ for rgb similar to the one in image_base.
+ * libmedia/gst/MediaDecoderGst.cpp: Exclude some code relying on old
+ VideoDecoderGst behaviour.
+ * libmedia/gst/VideoDecoderGst.{cpp,h}: Reimplement VideoDecoderGst
+ with a simple push/pop interface. Add a class gnashGstBuffer which
+ wraps the reference counted GstBuffer as a subclass of image::rgb.
+ This fixes bug #22067.
+ * libmedia/gst/gstappsink.{c,h}: Statically load this gstreamer
+ module. Add a non-blocking method for peeking the queue.
+ * libmedia/gst/gstappsrc.c: Statically load the appsrc module.
+ * server/asobj/NetStream.{cpp,h}: Change the argument to seek() from
+ milliseconds to seconds, because that's what is received from
+ ActionScript.
+ * server/asobj/NetStreamGst.cpp: Add a missing break in the message
+ parsing switch.
+ * server/parser/video_stream_def.{cpp,h}: Use the new VideoStreamGst
+ implementation.
+
2008-01-26 Sandro Santilli <address@hidden>
* testsuite/misc-ming.all/: FlashVarsTest.as, FlashVarsTest.html,
Index: configure.ac
===================================================================
RCS file: /sources/gnash/gnash/configure.ac,v
retrieving revision 1.476
retrieving revision 1.477
diff -u -b -r1.476 -r1.477
--- configure.ac 25 Jan 2008 20:56:02 -0000 1.476
+++ configure.ac 27 Jan 2008 07:18:16 -0000 1.477
@@ -1497,7 +1497,9 @@
if test "$media_handler" = "gst"; then
AC_PATH_PROG(GST_INSPECT, gst-inspect, ,[${pathlist}])
if test "x$GST_INSPECT" != "x" -a x"${darwin}" = xno ; then
- codecs="ffdemux_flv ffdemux_mp3 vorbisdec ffdec_vp6"
+ dnl FIXME: there may be multiple acceptable plugins that are acceptable for
+ dnl our use. For example, mad or ffmpeg will play mp3.
+ codecs="ffdec_flv ffdec_flashsv ffdec_vp6f ffdec_flashsv mad vorbisdec
ffdec_vp6"
for i in $codecs; do
hits="`$GST_INSPECT $i | grep -c 'Long name'`"
if test $hits -eq 0; then
Index: backend/render_handler_ogl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/render_handler_ogl.cpp,v
retrieving revision 1.104
retrieving revision 1.105
diff -u -b -r1.104 -r1.105
--- backend/render_handler_ogl.cpp 21 Jan 2008 20:56:05 -0000 1.104
+++ backend/render_handler_ogl.cpp 27 Jan 2008 07:18:17 -0000 1.105
@@ -671,8 +671,6 @@
virtual void reallyDrawVideoFrame(image::image_base* baseframe, const
matrix* m, const rect* bounds)
{
- GNASH_REPORT_FUNCTION;
-
image::rgb* frame = static_cast<image::rgb*>(baseframe);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
Index: libbase/image.cpp
===================================================================
RCS file: /sources/gnash/gnash/libbase/image.cpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -b -r1.26 -r1.27
--- libbase/image.cpp 12 Dec 2007 10:06:59 -0000 1.26
+++ libbase/image.cpp 27 Jan 2008 07:18:17 -0000 1.27
@@ -55,7 +55,7 @@
assert(from.m_pitch == m_pitch);
assert(m_size <= from.m_size);
assert(m_type == from.m_type);
- memcpy(m_data.get(), from.m_data.get(), m_size);
+ memcpy(m_data.get(), const_cast<image_base&>(from).data(),
m_size);
}
boost::uint8_t* image_base::scanline(size_t y)
Index: libbase/image.h
===================================================================
RCS file: /sources/gnash/gnash/libbase/image.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- libbase/image.h 12 Dec 2007 10:06:59 -0000 1.19
+++ libbase/image.h 27 Jan 2008 07:18:17 -0000 1.20
@@ -98,7 +98,7 @@
void update(const image_base& from);
/// Return a pointer to the underlying data
- boost::uint8_t* data() { return m_data.get(); }
+ virtual boost::uint8_t* data() { return m_data.get(); }
/// Return a pointer to first byte of given line
DSOEXPORT boost::uint8_t* scanline(size_t y);
@@ -160,6 +160,10 @@
image_base(o)
{}
+ rgb(uint8_t* data, int width, int height, int stride)
+ : image_base(data, width, height, stride, RGB)
+ {}
+
std::auto_ptr<image_base> clone() const
{
return std::auto_ptr<image_base>(new rgb(*this));
Index: libmedia/gst/MediaDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/MediaDecoderGst.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- libmedia/gst/MediaDecoderGst.cpp 21 Jan 2008 23:10:15 -0000 1.3
+++ libmedia/gst/MediaDecoderGst.cpp 27 Jan 2008 07:18:18 -0000 1.4
@@ -16,7 +16,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: MediaDecoderGst.cpp,v 1.3 2008/01/21 23:10:15 rsavoye Exp $
+// $Id: MediaDecoderGst.cpp,v 1.4 2008/01/27 07:18:18 bjacques Exp $
#include "MediaDecoderGst.h"
#include "AudioDecoderNellymoser.h"
@@ -81,6 +81,7 @@
bool MediaDecoderGst::setupDecoding()
{
+#if 0
std::auto_ptr<VideoInfo> vInfo = _parser->getVideoInfo();
if (vInfo.get() != NULL) {
@@ -96,7 +97,7 @@
log_error("No video decoder could be created, since no
decoder is enabled.");
}
}
-
+#endif
std::auto_ptr<AudioInfo> aInfo = _parser->getAudioInfo();
if (get_sound_handler() && aInfo.get() != NULL) {
Index: libmedia/gst/VideoDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- libmedia/gst/VideoDecoderGst.cpp 21 Jan 2008 23:10:15 -0000 1.9
+++ libmedia/gst/VideoDecoderGst.cpp 27 Jan 2008 07:18:18 -0000 1.10
@@ -16,254 +16,219 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoderGst.cpp,v 1.9 2008/01/21 23:10:15 rsavoye Exp $
+// $Id: VideoDecoderGst.cpp,v 1.10 2008/01/27 07:18:18 bjacques Exp $
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
#endif
-#ifdef SOUND_GST
-
#include "VideoDecoderGst.h"
+#include "gstappsink.h"
+#include "gstappsrc.h"
+
namespace gnash {
namespace media {
-VideoDecoderGst::VideoDecoderGst() :
- pipeline(NULL),
- input(NULL),
- inputcaps(NULL),
- videocaps(NULL),
- output(NULL),
- decoder(NULL),
- colorspace(NULL),
- decodedFrame(NULL),
- stop(false)
-
-{
-}
+// gstappsrc -> decodebin -> (decoder) -> ffmpegcolorspace -> gstappsink (with
rgb caps)
-VideoDecoderGst::~VideoDecoderGst()
-{
+// TODO: implement proper seeking.
- if (pipeline) {
- stop = true;
- delete input_lock;
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
- gst_object_unref (GST_OBJECT (pipeline));
- }
-}
+VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type)
+ : _appsink(NULL),
+ _colorspace(NULL)
-bool VideoDecoderGst::setup(VideoInfo* info)
{
- return setup(info->width, info->height, 0, true,
(videoCodecType)info->codec, 0);
-}
-
-bool
-VideoDecoderGst::setup(int widthi, int heighti, int deblockingi, bool
smoothingi, videoCodecType formati, int outputFormati)
-{
- // Save video attributes
- width = widthi;
- height = heighti;
- deblocking = deblockingi;
- smoothing = smoothingi;
- format = formati;
- outputFormat = outputFormati;
-
- // For now only H263/SVQ3, VP6 and screenvideo1 is supported
- if (format != VIDEO_CODEC_H263 && format != VIDEO_CODEC_VP6 && format
!= VIDEO_CODEC_SCREENVIDEO) return false;
-
- // init GStreamer
gst_init (NULL, NULL);
- // setup the pipeline
- pipeline = gst_pipeline_new (NULL);
+ _pipeline = gst_pipeline_new (NULL);
- // Setup the pipeline elements
+ _appsrc = gst_element_factory_make ("appsrc", NULL);
- // setup fake source
- input = gst_element_factory_make ("fakesrc", NULL);
- g_object_set (G_OBJECT (input), "sizetype", 3, /*"can-activate-pull",
FALSE,*/ "signal-handoffs", TRUE, NULL);
- // Setup the callback
- g_signal_connect (input, "handoff", G_CALLBACK
(VideoDecoderGst::callback_handoff), this);
-
- // Setup the input capsfilter
- inputcaps = gst_element_factory_make ("capsfilter", NULL);
+ GstElement* decoder = NULL;
GstCaps* caps = NULL;
- if (format == VIDEO_CODEC_H263) {
- caps = gst_caps_new_simple ("video/x-flash-video",
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- "framerate", GST_TYPE_FRACTION, 25, 1,
- "flvversion", G_TYPE_INT, 1,
- NULL);
- } else if (format == VIDEO_CODEC_VP6) {
- caps = gst_caps_new_simple ("video/x-vp6-flash",
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- "framerate", GST_TYPE_FRACTION, 25, 1,
- NULL);
- } else if (format == VIDEO_CODEC_SCREENVIDEO) {
- caps = gst_caps_new_simple ("video/x-flash-screen",
- "width", G_TYPE_INT, width,
- "height", G_TYPE_INT, height,
- "framerate", GST_TYPE_FRACTION, 25, 1,
- NULL);
- }
- if ( caps )
- {
- g_object_set (G_OBJECT (inputcaps), "caps", caps, NULL);
- gst_caps_unref (caps);
-#ifndef NDEBUG
- caps = NULL; // to check it is not null on next use ...
-#endif
+ switch (codec_type) {
+ case VIDEO_CODEC_H263:
+ decoder = gst_element_factory_make ("ffdec_flv", NULL);
+ caps = gst_caps_new_simple ("video/x-flash-video", NULL);
+ break;
+ case VIDEO_CODEC_VP6:
+ case VIDEO_CODEC_VP6A:
+ decoder = gst_element_factory_make ("ffdec_vp6f", NULL);
+ caps = gst_caps_new_simple ("video/x-vp6-flash", NULL);
+ break;
+ case VIDEO_CODEC_SCREENVIDEO:
+ case VIDEO_CODEC_SCREENVIDEO2:
+ decoder = gst_element_factory_make ("ffdec_flashsv", NULL);
+ caps = gst_caps_new_simple ("video/x-flash-screen", NULL);
+ break;
+ default:
+ log_error("No support for this video codec. %d", codec_type);
+ gst_object_unref (GST_OBJECT (_pipeline));
+ _pipeline = NULL;
+ return;
}
- else
- {
- log_error("Unknown codec format %d", format);
+
+ if (!decoder) {
+ log_error(_("failed to initialize the video decoder. Bailing out."));
+ gst_object_unref (GST_OBJECT (_pipeline));
+ gst_caps_unref(caps);
+ _pipeline = NULL;
+ return;
}
- // Setup the capsfilter which demands either YUV or RGB videoframe
format
- videocaps = gst_element_factory_make ("capsfilter", NULL);
+ gst_app_src_set_caps (GST_APP_SRC(_appsrc), caps);
+ gst_caps_unref(caps);
+
+ _colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
+
+ _appsink = gst_element_factory_make ("appsink", NULL);
+
+
caps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
- assert(caps); // ok, this is a silly assertion *now*, but as long as
- // the code is implemented with such long function bodies
- // a day will come in which someone will change something
- // a few screefulls above and the assertion would make
- // sense (maybe boost compile-time assertions could help
- // in this reguard).
+ gst_app_sink_set_caps(GST_APP_SINK(_appsink), caps);
- g_object_set (G_OBJECT (videocaps), "caps", caps, NULL);
gst_caps_unref (caps);
- // setup the videosink with callback
- output = gst_element_factory_make ("fakesink", NULL);
- g_object_set (G_OBJECT (output), "signal-handoffs", TRUE, NULL);
- g_signal_connect (output, "handoff", G_CALLBACK
(VideoDecoderGst::callback_output), this);
- // setup the video colorspaceconverter converter
- colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
+ gst_bin_add_many (GST_BIN (_pipeline), _appsrc, decoder, _colorspace,
_appsink, NULL);
- // Find the decoder, use auto plugin loader? use plugin-downloader?
- if (format == VIDEO_CODEC_H263) {
- decoder = gst_element_factory_make ("ffdec_flv", NULL);
- } else if (format == VIDEO_CODEC_VP6) {
- decoder = gst_element_factory_make ("ffdec_vp6f", NULL);
- } else if (format == VIDEO_CODEC_SCREENVIDEO) {
- decoder = gst_element_factory_make ("ffdec_flashsv", NULL);
- } else {
- gnash::log_error("Unsupported embedded video format");
- return false;
+ gst_element_link_many(_appsrc, decoder, _colorspace, _appsink, NULL);
+
+ gst_base_src_set_live(GST_BASE_SRC(_appsrc), TRUE);
+
+ gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_PLAYING);
+}
+
+VideoDecoderGst::~VideoDecoderGst()
+{
+ if (_pipeline) {
+ gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (_pipeline));
}
+}
- if (!pipeline || !input || !inputcaps || !videocaps || !output ||
!colorspace) {
- gnash::log_error("Creation of Gstreamer baisc elements failed,
is your Gstreamer installation complete?");
- return false;
+void
+VideoDecoderGst::pushRawFrame(GstBuffer* buffer)
+{
+ if (!_pipeline) {
+ return;
}
+ gst_app_src_push_buffer (GST_APP_SRC(_appsrc), buffer);
+}
- if (!decoder) {
- gnash::log_error("Creation of decoder element failed, do you
have gstreamer-0.10-ffmpeg installed?");
- return false;
+
+std::auto_ptr<gnashGstBuffer>
+VideoDecoderGst::popDecodedFrame()
+{
+ if (!_pipeline) {
+ return std::auto_ptr<gnashGstBuffer>();
}
- // Put the elemets in the pipeline and link them
- gst_bin_add_many (GST_BIN (pipeline), input, inputcaps, decoder,
colorspace, videocaps, output, NULL);
+ checkMessages();
+
+ GstBuffer* buffer = gst_app_sink_pull_buffer (GST_APP_SINK(_appsink));
+ GstCaps* caps = gst_buffer_get_caps(buffer);
- // link the elements
- gst_element_link_many(input, inputcaps, decoder, colorspace, videocaps,
output, NULL);
+ assert(gst_caps_get_size(caps) == 1);
- // This make callback_handoff wait for data
- input_lock = new boost::mutex::scoped_lock(input_mutex);
+ GstStructure* structure = gst_caps_get_structure (caps, 0);
- // This make decodeFrame wait for data
- output_lock = new boost::mutex::scoped_lock(output_mutex);
+ gint height, width;
- // Determine required buffer size and allocate buffer
- decodedFrame.reset(new image::rgb(width, height));
+ gst_structure_get_int (structure, "width", &width);
+ gst_structure_get_int (structure, "height", &height);
- // Start "playing"
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+ gst_caps_unref(caps);
- return true;
+ std::auto_ptr<gnashGstBuffer> ret(new gnashGstBuffer(buffer, width, height));
+
+ return ret;
}
-// gnash calls this when it wants you to decode the given videoframe
-std::auto_ptr<image::image_base>
-VideoDecoderGst::decodeToImage(boost::uint8_t* data, boost::uint32_t size)
+bool
+VideoDecoderGst::peek()
{
+ if (!_pipeline) {
+ return false;
+ }
- std::auto_ptr<image::image_base> ret_image(new image::rgb(width,
height));
+ return gst_app_sink_peek_buffer (GST_APP_SINK(_appsink));
+}
- // If there is nothing to decode in the new frame
- // we just return the lastest.
- if (data == NULL || size == 0 || !decoder)
- {
- // If we never decoded any frame return a NULL
- // auto pointer ..
- if ( ! decodedFrame.get() )
- {
- return std::auto_ptr<image::image_base>(NULL);
+void
+VideoDecoderGst::reset()
+{
+ if (!_pipeline) {
+ return;
}
- ret_image->update(*decodedFrame);
- return ret_image;
+ gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_NULL); // Flushes
+ gst_element_set_state (GST_ELEMENT (_pipeline), GST_STATE_PLAYING);
+}
+
+void
+VideoDecoderGst::checkMessages() // any messages for me?
+{
+ if (!_pipeline) {
+ return;
}
- frame = data;
- frameSize = size;
-//printf("datasize: %d\n", size);
- delete input_lock;
+ GstBus* bus = gst_element_get_bus(_pipeline);
- output_lock = new boost::mutex::scoped_lock(output_mutex);
+ while (gst_bus_have_pending(bus)) {
+ GstMessage* msg = gst_bus_pop(bus);
+ handleMessage(msg);
- // If we never decoded any frame return a NULL
- // auto pointer ..
- if ( ! decodedFrame.get() )
- {
- return std::auto_ptr<image::image_base>(NULL);
+ gst_message_unref(msg);
}
- // return decodedFrame->clone() ?
- ret_image->update(*decodedFrame);
- return ret_image;
+ gst_object_unref(GST_OBJECT(bus));
}
-// The callback function which refills the buffer with data
void
-VideoDecoderGst::callback_handoff (GstElement * /*c*/, GstBuffer *buffer,
GstPad* /*pad*/, gpointer user_data)
+VideoDecoderGst::handleMessage (GstMessage *message)
{
- VideoDecoderGst* decoder = static_cast<VideoDecoderGst*>(user_data);
+#if 0
+ g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
+#endif
- if (decoder->stop) return;
+ switch (GST_MESSAGE_TYPE (message)) {
+ case GST_MESSAGE_ERROR:
+ {
+ GError *err;
+ gchar *debug;
+ gst_message_parse_error (message, &err, &debug);
- decoder->input_lock = new
boost::mutex::scoped_lock(decoder->input_mutex);
+ log_error(_("Embedded video playback halted; module %s reported: %s\n"),
+ gst_element_get_name(GST_MESSAGE_SRC (message)), err->message);
- GST_BUFFER_SIZE(buffer) = decoder->frameSize;
+ g_error_free (err);
+ g_free (debug);
- GST_BUFFER_DATA(buffer) = decoder->frame;
-}
+ // Clear any buffers.
+ gst_element_set_state (_pipeline, GST_STATE_NULL);
-// The callback function which passes the decoded video frame
-void
-VideoDecoderGst::callback_output (GstElement * /*c*/, GstBuffer *buffer,
GstPad* /*pad*/, gpointer user_data)
-{
- VideoDecoderGst* decoder = static_cast<VideoDecoderGst*>(user_data);
-//printf("datadecoded\n");
- if (decoder->stop) return;
+ break;
+ }
+ case GST_MESSAGE_EOS:
+ log_msg(_("NetStream has reached the end of the stream."));
- if (decoder->decodedFrame.get())
+ break;
+
+ default:
{
- decoder->decodedFrame->update(GST_BUFFER_DATA(buffer));
+#if 0
+ g_print("unhandled message\n");
+#endif
+ }
}
-
- delete decoder->output_lock;
}
-} // gnash.media namespace
-} // end of gnash namespace
-#endif // SOUND_GST
+} // namespace gnash::media
+} // namespace gnash
Index: libmedia/gst/VideoDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- libmedia/gst/VideoDecoderGst.h 21 Jan 2008 23:10:15 -0000 1.11
+++ libmedia/gst/VideoDecoderGst.h 27 Jan 2008 07:18:18 -0000 1.12
@@ -16,92 +16,93 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// $Id: VideoDecoderGst.h,v 1.11 2008/01/21 23:10:15 rsavoye Exp $
+// $Id: VideoDecoderGst.h,v 1.12 2008/01/27 07:18:18 bjacques Exp $
#ifndef __VIDEODECODERGST_H__
#define __VIDEODECODERGST_H__
+
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
#endif
+#include "image.h"
+#include <gst/gst.h>
#include "log.h"
-#include "VideoDecoder.h"
+#include "MediaParser.h"
-#include <gst/gst.h>
-#include "image.h"
-#include <boost/thread/thread.hpp>
-#include <boost/bind.hpp>
-#include <boost/thread/mutex.hpp>
namespace gnash {
namespace media {
-/// Video decoding using Gstreamer.
-class VideoDecoderGst : public VideoDecoder {
-
+// Convenience wrapper for GstBuffer. Intended to be wrapped in an auto_ptr.
+class gnashGstBuffer : public image::rgb
+{
public:
- VideoDecoderGst();
- ~VideoDecoderGst();
+ gnashGstBuffer(GstBuffer* buf, int width, int height)
+ : rgb(NULL, width, height, (width * 3 + 3) & ~3),
+ _buffer(buf)
+ {}
+
+ ~gnashGstBuffer()
+ {
+ gst_buffer_unref(_buffer);
+ }
+
+ boost::uint8_t* data()
+ {
+ return GST_BUFFER_DATA(_buffer);
+ }
+
+ std::auto_ptr<image::image_base> clone() const
+ {
+ return std::auto_ptr<image_base>(new rgb(*this));
+ }
- bool setup(VideoInfo* info);
+private:
+ GstBuffer* _buffer;
+};
- bool setup(
- int /*width*/,
- int /*height*/,
- int /*deblocking*/,
- bool /*smoothing*/,
- videoCodecType /*format*/,
- int /*outputFormat*/);
- //boost::uint8_t* decode(boost::uint8_t* input, boost::uint32_t
inputSize, boost::uint32_t& outputSize);
+class VideoDecoderGst
+{
+public:
+
+ VideoDecoderGst(videoCodecType codec_type);
+ ~VideoDecoderGst();
- std::auto_ptr<image::image_base> decodeToImage(boost::uint8_t*
/*input*/, boost::uint32_t /*inputSize*/);
+ void pushRawFrame(GstBuffer* buffer);
- static void callback_handoff (GstElement * /*c*/, GstBuffer *buffer,
GstPad* /*pad*/, gpointer user_data);
- static void callback_output (GstElement * /*c*/, GstBuffer *buffer,
GstPad* /*pad*/, gpointer user_data);
-private:
+ /// Will block
+ std::auto_ptr<gnashGstBuffer> popDecodedFrame();
- // gstreamer pipeline objects
+ /// Returns true if there is a decoded frame ready to be popped.
+ bool peek();
- /// the main bin containing the elements
- GstElement *pipeline;
+ /// Clears the pipeline so that the stream can start from scratch.
+ void reset();
- /// Gstreamer objects
- GstElement *input;
- GstElement *inputcaps;
- GstElement *videocaps;
- GstElement *output;
- GstElement *decoder;
- GstElement *colorspace;
-
- /// mutexes and locks used to handle input and output.
- boost::mutex input_mutex;
- boost::mutex output_mutex;
- boost::mutex::scoped_lock* input_lock;
- boost::mutex::scoped_lock* output_lock;
-
- /// Info from the video tag header. Might be usefull...
- boost::uint32_t width;
- boost::uint32_t height;
- int deblocking;
- bool smoothing;
- videoCodecType format;
- int outputFormat;
-
- /// Input data and size for current frame
- boost::uint8_t* frame;
- int frameSize;
+ void checkMessages();
- /// Last decoded frame
- std::auto_ptr<image::image_base> decodedFrame;
+ static void
+ decodebin_newpad_cb(GstElement* decodebin, GstPad* pad,
+ gboolean last, gpointer user_data);
+ static void
+ decodebin_unknown_cb(GstElement* decodebin, GstPad* pad,
+ gboolean last, gpointer user_data);
- /// If we should stop this will be true
- volatile bool stop;
+ void handleMessage(GstMessage* message);
+private:
+ VideoDecoderGst();
+ VideoDecoderGst(const gnash::media::VideoDecoderGst&);
+ GstElement* _pipeline;
+ GstElement* _appsrc;
+ GstElement* _appsink;
+ GstElement* _colorspace;
};
-} // gnash.media namespace
-} // gnash namespace
+} // namespace media
+} // namespace gnash
#endif // __VIDEODECODERGST_H__
Index: libmedia/gst/gstappsink.c
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/gstappsink.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libmedia/gst/gstappsink.c 21 Jan 2008 23:10:15 -0000 1.4
+++ libmedia/gst/gstappsink.c 27 Jan 2008 07:18:18 -0000 1.5
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* $Id: gstappsink.c,v 1.4 2008/01/21 23:10:15 rsavoye Exp $ */
+/* $Id: gstappsink.c,v 1.5 2008/01/27 07:18:18 bjacques Exp $ */
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -414,6 +414,26 @@
return caps;
}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "Application sink");
+
+ if (!gst_element_register (plugin, "appsink", GST_RANK_PRIMARY,
+ gst_app_sink_get_type ()))
+ return FALSE;
+
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR,
+ "appsink", "Element application sink",
+ plugin_init, VERSION, "LGPL", "Gnash's internal copy of gstappsink",
"Gnash")
+
+
+
+
/* external API */
/**
@@ -646,3 +666,27 @@
return NULL;
}
}
+
+
+/**
+ * gst_app_sink_peek_buffer:
+ * @appsink: a #GstAppSink
+ *
+ * This function peeks the queue to see if at least one buffer is in the queue.
+ *
+ * Returns: TRUE if there is a buffer in the queue.
+ */
+gboolean
+gst_app_sink_peek_buffer (GstAppSink * appsink)
+{
+ g_return_val_if_fail (appsink != NULL, NULL);
+ g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
+
+ g_mutex_lock (appsink->mutex);
+
+ gboolean got_data = !g_queue_is_empty(appsink->queue);
+
+ g_mutex_unlock (appsink->mutex);
+
+ return got_data;
+}
Index: libmedia/gst/gstappsink.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/gstappsink.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- libmedia/gst/gstappsink.h 4 Oct 2007 09:37:50 -0000 1.3
+++ libmedia/gst/gstappsink.h 27 Jan 2008 07:18:18 -0000 1.4
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* $Id: gstappsink.h,v 1.3 2007/10/04 09:37:50 tgc Exp $ */
+/* $Id: gstappsink.h,v 1.4 2008/01/27 07:18:18 bjacques Exp $ */
#ifndef _GST_APP_SINK_H_
#define _GST_APP_SINK_H_
@@ -81,6 +81,7 @@
GstBuffer * gst_app_sink_pull_preroll (GstAppSink *appsink);
GstBuffer * gst_app_sink_pull_buffer (GstAppSink *appsink);
+gboolean gst_app_sink_peek_buffer (GstAppSink *appsink);
G_END_DECLS
Index: libmedia/gst/gstappsrc.c
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/gstappsrc.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libmedia/gst/gstappsrc.c 21 Jan 2008 23:10:15 -0000 1.4
+++ libmedia/gst/gstappsrc.c 27 Jan 2008 07:18:19 -0000 1.5
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* $Id: gstappsrc.c,v 1.4 2008/01/21 23:10:15 rsavoye Exp $ */
+/* $Id: gstappsrc.c,v 1.5 2008/01/27 07:18:19 bjacques Exp $ */
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -236,6 +236,22 @@
return ret;
}
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ GST_DEBUG_CATEGORY_INIT (app_src_debug, "appsrc", 0, "Application source");
+
+ if (!gst_element_register (plugin, "appsrc", GST_RANK_PRIMARY,
+ gst_app_src_get_type ()))
+ return FALSE;
+
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR,
+ "appsrc", "Element application source",
+ plugin_init, VERSION, "LGPL", "Gnash's internal copy of gstappsrc",
"Gnash")
+
/* external API */
Index: server/asobj/NetStream.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.cpp,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -b -r1.83 -r1.84
--- server/asobj/NetStream.cpp 22 Jan 2008 14:37:10 -0000 1.83
+++ server/asobj/NetStream.cpp 27 Jan 2008 07:18:19 -0000 1.84
@@ -17,7 +17,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-/* $Id: NetStream.cpp,v 1.83 2008/01/22 14:37:10 strk Exp $ */
+/* $Id: NetStream.cpp,v 1.84 2008/01/27 07:18:19 bjacques Exp $ */
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -173,7 +173,7 @@
{
time = fn.arg(0).to_number<boost::uint32_t>();
}
- ns->seek(static_cast<boost::uint32_t>(time*1000.0));
+ ns->seek(time);
return as_value();
}
Index: server/asobj/NetStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.h,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -b -r1.57 -r1.58
--- server/asobj/NetStream.h 22 Jan 2008 14:37:10 -0000 1.57
+++ server/asobj/NetStream.h 27 Jan 2008 07:18:19 -0000 1.58
@@ -15,7 +15,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: NetStream.h,v 1.57 2008/01/22 14:37:10 strk Exp $ */
+/* $Id: NetStream.h,v 1.58 2008/01/27 07:18:19 bjacques Exp $ */
#ifndef __NETSTREAM_H__
#define __NETSTREAM_H__
@@ -218,7 +218,7 @@
/// Seek in the media played by the current instance
//
/// @param position
- /// Defines in milliseconds where to seek to
+ /// Defines in seconds where to seek to
///
virtual void seek(boost::uint32_t /*pos*/){}
Index: server/asobj/NetStreamGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.cpp,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -b -r1.74 -r1.75
--- server/asobj/NetStreamGst.cpp 25 Jan 2008 20:54:59 -0000 1.74
+++ server/asobj/NetStreamGst.cpp 27 Jan 2008 07:18:19 -0000 1.75
@@ -541,6 +541,7 @@
// Sometimes the pipeline fails to use this number in queries.
GstFormat format = GST_FORMAT_BYTES;
gst_message_parse_duration(message, &format, &_duration);
+ break;
}
default:
Index: server/parser/video_stream_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- server/parser/video_stream_def.cpp 21 Jan 2008 20:56:01 -0000 1.33
+++ server/parser/video_stream_def.cpp 27 Jan 2008 07:18:20 -0000 1.34
@@ -16,34 +16,38 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: video_stream_def.cpp,v 1.33 2008/01/21 20:56:01 rsavoye Exp $
+// $Id: video_stream_def.cpp,v 1.34 2008/01/27 07:18:20 bjacques Exp $
#include "video_stream_def.h"
#include "video_stream_instance.h"
#include "render.h"
#include "BitsReader.h"
-#ifdef USE_FFMPEG
-#include "VideoDecoderFfmpeg.h"
-#elif defined(SOUND_GST)
#include "VideoDecoderGst.h"
-#endif
+#include <boost/bind.hpp>
+
namespace gnash {
video_stream_definition::video_stream_definition(boost::uint16_t char_id)
:
m_char_id(char_id),
- m_last_decoded_frame(-1),
+ _last_decoded_frame(-1),
_width(0),
_height(0),
_decoder(NULL)
{
}
+void myunref(GstBuffer* buf)
+{
+ gst_buffer_unref(buf);
+}
+
video_stream_definition::~video_stream_definition()
{
+ std::for_each(_video_frames.begin(), _video_frames.end(), myunref);
}
@@ -75,15 +79,7 @@
m_codec_id = static_cast<media::videoCodecType>(in->read_u8());
-#ifdef USE_FFMPEG
- _decoder.reset( new media::VideoDecoderFfmpeg() );
-#elif defined(SOUND_GST)
- _decoder.reset( new media::VideoDecoderGst() );
-#else
- _decoder.reset( new media::VideoDecoder() );
-#endif
- bool ret = _decoder->setup(_width, _height, m_deblocking_flags,
m_smoothing_flags, m_codec_id, gnash::render::videoFrameFormat());
- if (!ret) _decoder.reset(new media::VideoDecoder()); // This is so
statically-defined video_stream_def always have a _decoder != NULL
+ _decoder.reset( new media::VideoDecoderGst(m_codec_id) );
}
@@ -104,49 +100,27 @@
frameNum = m->get_loading_frame();
}
- // We need to make the buffer a FF_INPUT_BUFFER_PADDING_SIZE
- // bigger than the data to avoid libavcodec (ffmpeg) making
- // illegal reads. Also, we must ensure first 23 bits to be
- // zeroed out. We'll zero out all padding.
- unsigned int padding = _decoder->getPaddingBytes();
unsigned int dataSize = in->get_tag_end_position() - in->get_position();
- unsigned int totSize = dataSize+padding;
- boost::shared_array<boost::uint8_t> data ( new boost::uint8_t[totSize]
);
- in->read((char*)data.get(), dataSize);
- if ( padding ) memset(&data[dataSize], 0, padding); // pad with zeroes
if needed
-
-
- // Check what kind of frame this is
- media::videoFrameType ft;
- if (m_codec_id == media::VIDEO_CODEC_H263) {
- //log_debug("H263 embedded video!");
- // Parse the h263 header to determine the frame type. The
position of the
- // info varies if the frame size is custom.
- BitsReader br(data.get(), totSize);
- boost::uint32_t tmp = br.read_uint(30);
- tmp = br.read_uint(3);
- if (tmp == 0) tmp = br.read_uint(32);
- else if (tmp == 1) tmp = br.read_uint(16);
-
- // Finally we're at the info, read and use
- tmp = br.read_uint(3);
- if (tmp == 0) ft = media::KEY_FRAME;
- else if (tmp == 1) ft = media::INTER_FRAME;
- else ft = media::DIS_INTER_FRAME;
-
- } else if (m_codec_id == media::VIDEO_CODEC_VP6 || m_codec_id ==
media::VIDEO_CODEC_VP6A) {
- // Get the info from the VP6 header
- //if (!(data.get()[0] & 0x80)) ft = media::KEY_FRAME;
- if (! (data[0] & 0x80) ) ft = media::KEY_FRAME;
- else ft = media::INTER_FRAME;
+ GstBuffer* buffer = gst_buffer_new_and_alloc(dataSize);
- } else {
- ft = media::KEY_FRAME;
+ if (!buffer) {
+ log_error(_("Failed to allocate a buffer of size %d advertised
by SWF."),
+ dataSize);
+ return;
}
- setFrameData(frameNum, data, totSize, ft);
+ GST_BUFFER_OFFSET(buffer) = frameNum;
+
+ in->read((char*)GST_BUFFER_DATA(buffer), dataSize);
+ _video_frames.push_back(buffer);
+
+ if (frameNum == 0) {
+ gst_buffer_ref(buffer); // make sure gstreamer doesn't delete the
buffer.
+
+ _decoder->pushRawFrame(buffer);
+ }
}
@@ -157,56 +131,33 @@
return ch;
}
+bool
+has_frame_number(GstBuffer* buf, boost::uint32_t frameNumber)
+{
+ return GST_BUFFER_OFFSET(buf) == frameNumber;
+}
+
std::auto_ptr<image::image_base>
video_stream_definition::get_frame_data(boost::uint32_t frameNum)
{
+ // Check if the requested frame holds any video data.
+ EmbedFrameVec::iterator it = std::find_if(_video_frames.begin(),
+ _video_frames.end(), boost::bind(has_frame_number, _1, frameNum+1));
- // Check if the requested frame hold any video data.
- EmbedFrameMap::iterator it = m_video_frames.find(frameNum);
- if( it == m_video_frames.end() )
+ if( it == _video_frames.end() )
{
- log_debug(_("No video data available for frame %d."), frameNum);
- return std::auto_ptr<image::image_base>(NULL);
+ return std::auto_ptr<image::image_base>();
}
- // rewind to the nearest keyframe, or the last frame we decoded
- while (static_cast<boost::uint32_t>(m_last_decoded_frame+1) !=
it->first && it->second->frameType != media::KEY_FRAME && it !=
m_video_frames.begin()) it--;
+ gst_buffer_ref(*it); // make sure gstreamer doesn't delete the buffer.
- std::auto_ptr<image::image_base> ret(NULL);
-
- // Decode all the frames needed to produce the requested one
- while (it != m_video_frames.end() && it->first <= frameNum) {
- // If this is a disposable interlaced frame, and it is not the
- // last one to be decoded, we skip the decoding.
- if (!(it->second->frameType == media::DIS_INTER_FRAME &&
it->first != frameNum)) {
- ret.reset(NULL);
- ret =
_decoder->decodeToImage(it->second->videoData.get(), it->second->dataSize);
- }
- it++;
- }
-
- m_last_decoded_frame = frameNum;
-
- return ret;
+ _decoder->pushRawFrame(*it);
+ return std::auto_ptr<image::image_base>(_decoder->popDecodedFrame());
}
-void
-video_stream_definition::setFrameData(boost::uint32_t frameNum,
boost::shared_array<boost::uint8_t> data, boost::uint32_t size,
media::videoFrameType ft)
-{
- EmbedFrameMap::iterator it = m_video_frames.find(frameNum);
- if( it != m_video_frames.end() )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror(_("Mulitple video frames defined for frame %u"),
frameNum);
- );
- return;
- }
- boost::shared_ptr<VideoData> vd (new VideoData(data, size,ft));
- m_video_frames[frameNum] = vd;
-}
} // namespace gnash
Index: server/parser/video_stream_def.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/parser/video_stream_def.h 21 Jan 2008 20:56:01 -0000 1.21
+++ server/parser/video_stream_def.h 27 Jan 2008 07:18:20 -0000 1.22
@@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: video_stream_def.h,v 1.21 2008/01/21 20:56:01 rsavoye Exp $
+// $Id: video_stream_def.h,v 1.22 2008/01/27 07:18:20 bjacques Exp $
#ifndef GNASH_VIDEO_STREAM_DEF_H
#define GNASH_VIDEO_STREAM_DEF_H
@@ -31,7 +31,7 @@
#include "swf.h"
#include "rect.h" // for composition
#include "ControlTag.h"
-#include "VideoDecoder.h"
+#include "VideoDecoderGst.h"
#include "image.h"
#include <map>
@@ -154,30 +154,14 @@
/// The undecoded video frames and its size, using the swf-frame number
as key
//
- /// Elements of this map are owned by this instance, and will be
deleted
+ /// Elements of this vector are owned by this instance, and will be
deleted
/// at instance destruction time.
///
- typedef std::map<boost::uint32_t, boost::shared_ptr<VideoData> >
EmbedFrameMap;
- EmbedFrameMap m_video_frames;
+ typedef std::vector<GstBuffer*> EmbedFrameVec;
+ EmbedFrameVec _video_frames;
/// Last decoded frame number
- boost::int32_t m_last_decoded_frame;
-
- /// Set data for the given frame
- //
- /// If a frame image is already known for the given frame number
- /// it will NOT be replaced, and an SWF error will be printed.
- /// The 'img' parameter will be deleted.
- ///
- /// See get_frame_data to extract it.
- ///
- /// @param frameNum
- /// Frame number.
- ///
- /// @param img
- /// Frame data. Ownership is transferred.
- ///
- void setFrameData(boost::uint32_t frameNum,
boost::shared_array<boost::uint8_t> data, boost::uint32_t size,
media::videoFrameType ft);
+ boost::int32_t _last_decoded_frame;
/// Width of the video
boost::uint32_t _width;
@@ -186,7 +170,7 @@
boost::uint32_t _height;
/// The decoder used to decode the video frames
- boost::scoped_ptr<media::VideoDecoder> _decoder;
+ boost::scoped_ptr<media::VideoDecoderGst> _decoder;
};
} // end namespace gnash
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog configure.ac backend/render_han...,
Bastiaan Jacques <=