[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog libmedia/gst/VideoDecoderGst.cp...
From: |
Bastiaan Jacques |
Subject: |
[Gnash-commit] gnash ChangeLog libmedia/gst/VideoDecoderGst.cp... |
Date: |
Tue, 29 Jan 2008 05:18:34 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Bastiaan Jacques <bjacques> 08/01/29 05:18:34
Modified files:
. : ChangeLog
libmedia/gst : VideoDecoderGst.cpp VideoDecoderGst.h
gstappsink.c gstappsink.h
server/parser : video_stream_def.cpp
Log message:
* libmedia/gst/VideoDecoderGst.{cpp,h}: Tell the decoder about
the
expected video width and height. Check for error conditions more
frequently.
* libmedia/gst/gstappsink.{c,h}: Add
gst_app_sink_pull_buffer_timed(), which waits up to one second
before returning if the expected buffer does not make its way
to the output queue.
* server/parser/video_stream_def.cpp: Make sure the decoder
parses
intermedia frames if certain frames are skipped. Don't assume
that
frame 0 is a "spin-up" frame. Fixes Video-EmbedSquareTest.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5513&r2=1.5514
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.cpp?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/VideoDecoderGst.h?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/gstappsink.c?cvsroot=gnash&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/gst/gstappsink.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/video_stream_def.cpp?cvsroot=gnash&r1=1.35&r2=1.36
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5513
retrieving revision 1.5514
diff -u -b -r1.5513 -r1.5514
--- ChangeLog 28 Jan 2008 20:36:28 -0000 1.5513
+++ ChangeLog 29 Jan 2008 05:18:32 -0000 1.5514
@@ -1,3 +1,16 @@
+2008-01-28 Bastiaan Jacques <address@hidden>
+
+ * libmedia/gst/VideoDecoderGst.{cpp,h}: Tell the decoder about the
+ expected video width and height. Check for error conditions more
+ frequently.
+ * libmedia/gst/gstappsink.{c,h}: Add
+ gst_app_sink_pull_buffer_timed(), which waits up to one second
+ before returning if the expected buffer does not make its way
+ to the output queue.
+ * server/parser/video_stream_def.cpp: Make sure the decoder parses
+ intermedia frames if certain frames are skipped. Don't assume that
+ frame 0 is a "spin-up" frame. Fixes Video-EmbedSquareTest.
+
2008-01-28 Sandro Santilli <address@hidden>
* server/swf/tag_loaders.cpp (button_sound_loader): robustness
Index: libmedia/gst/VideoDecoderGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- libmedia/gst/VideoDecoderGst.cpp 27 Jan 2008 07:18:18 -0000 1.10
+++ libmedia/gst/VideoDecoderGst.cpp 29 Jan 2008 05:18:33 -0000 1.11
@@ -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: VideoDecoderGst.cpp,v 1.10 2008/01/27 07:18:18 bjacques Exp $
+// $Id: VideoDecoderGst.cpp,v 1.11 2008/01/29 05:18:33 bjacques Exp $
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -34,10 +34,9 @@
// TODO: implement proper seeking.
-VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type)
+VideoDecoderGst::VideoDecoderGst(videoCodecType codec_type, int width, int
height)
: _appsink(NULL),
_colorspace(NULL)
-
{
gst_init (NULL, NULL);
@@ -46,22 +45,31 @@
_appsrc = gst_element_factory_make ("appsrc", NULL);
GstElement* decoder = NULL;
- GstCaps* caps = NULL;
+ GstCaps* caps;
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);
+ caps = gst_caps_new_simple ("video/x-flash-video",
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ 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);
+ caps = gst_caps_new_simple ("video/x-vp6-flash",
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ 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);
+ decoder = gst_element_factory_make ("ffdec_flv", NULL);
+ caps = gst_caps_new_simple ("video/x-flash-screen",
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ NULL);
break;
default:
log_error("No support for this video codec. %d", codec_type);
@@ -73,7 +81,6 @@
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;
}
@@ -117,6 +124,8 @@
return;
}
gst_app_src_push_buffer (GST_APP_SRC(_appsrc), buffer);
+
+ checkMessages();
}
@@ -129,7 +138,12 @@
checkMessages();
- GstBuffer* buffer = gst_app_sink_pull_buffer (GST_APP_SINK(_appsink));
+ GstBuffer* buffer = gst_app_sink_pull_buffer_timed (GST_APP_SINK(_appsink));
+
+ if (!buffer) {
+ return std::auto_ptr<gnashGstBuffer>();
+ }
+
GstCaps* caps = gst_buffer_get_caps(buffer);
assert(gst_caps_get_size(caps) == 1);
Index: libmedia/gst/VideoDecoderGst.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/VideoDecoderGst.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- libmedia/gst/VideoDecoderGst.h 27 Jan 2008 07:18:18 -0000 1.12
+++ libmedia/gst/VideoDecoderGst.h 29 Jan 2008 05:18:33 -0000 1.13
@@ -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: VideoDecoderGst.h,v 1.12 2008/01/27 07:18:18 bjacques Exp $
+// $Id: VideoDecoderGst.h,v 1.13 2008/01/29 05:18:33 bjacques Exp $
#ifndef __VIDEODECODERGST_H__
#define __VIDEODECODERGST_H__
@@ -68,7 +68,7 @@
{
public:
- VideoDecoderGst(videoCodecType codec_type);
+ VideoDecoderGst(videoCodecType codec_type, int width, int height);
~VideoDecoderGst();
void pushRawFrame(GstBuffer* buffer);
Index: libmedia/gst/gstappsink.c
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/gstappsink.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- libmedia/gst/gstappsink.c 27 Jan 2008 07:18:18 -0000 1.5
+++ libmedia/gst/gstappsink.c 29 Jan 2008 05:18:33 -0000 1.6
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* $Id: gstappsink.c,v 1.5 2008/01/27 07:18:18 bjacques Exp $ */
+/* $Id: gstappsink.c,v 1.6 2008/01/29 05:18:33 bjacques Exp $ */
#ifdef HAVE_CONFIG_H
#include "gnashconfig.h"
@@ -669,6 +669,85 @@
/**
+ * gst_app_sink_pull_buffer_timed:
+ * @appsink: a #GstAppSink
+ *
+ * This function blocks until a buffer or EOS becomes available or the appsink
+ * element is set to the READY/NULL state, or if one second elapses.
+ *
+ * This function will only return buffers when the appsink is in the PLAYING
+ * state. All rendered buffers will be put in a queue so that the application
+ * can pull buffers at its own rate.
+ *
+ * If an EOS event was received before any buffers, or if one second passes and
+ * no data arrives, this function returns * %NULL. Use gst_app_sink_is_eos ()
+ * to check for the EOS condition.
+ *
+ * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS, or one
+ * second elapses.
+ */
+GstBuffer *
+gst_app_sink_pull_buffer_timed (GstAppSink * appsink)
+{
+ GstBuffer *buf = NULL;
+
+ g_return_val_if_fail (appsink != NULL, NULL);
+ g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
+
+ g_mutex_lock (appsink->mutex);
+
+ while (TRUE) {
+ GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
+ if (!appsink->started)
+ goto not_started;
+
+ if (!g_queue_is_empty (appsink->queue))
+ break;
+
+ if (appsink->is_eos)
+ goto eos;
+
+ /* nothing to return, wait */
+ GST_DEBUG_OBJECT (appsink, "waiting for a buffer");
+
+ GTimeVal cur_time;
+ g_get_current_time(&cur_time);
+ cur_time.tv_sec++; // Add one second
+
+ if (!g_cond_timed_wait(appsink->cond, appsink->mutex, &cur_time))
+ goto timeout;
+
+ }
+ buf = g_queue_pop_head (appsink->queue);
+ GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buf);
+ g_mutex_unlock (appsink->mutex);
+
+ return buf;
+
+ /* special conditions */
+timeout:
+ {
+ GST_DEBUG_OBJECT (appsink, "we timed out, return NULL");
+ g_mutex_unlock (appsink->mutex);
+ return NULL;
+ }
+eos:
+ {
+ GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
+ g_mutex_unlock (appsink->mutex);
+ return NULL;
+ }
+not_started:
+ {
+ GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
+ g_mutex_unlock (appsink->mutex);
+ return NULL;
+ }
+}
+
+
+
+/**
* gst_app_sink_peek_buffer:
* @appsink: a #GstAppSink
*
Index: libmedia/gst/gstappsink.h
===================================================================
RCS file: /sources/gnash/gnash/libmedia/gst/gstappsink.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- libmedia/gst/gstappsink.h 27 Jan 2008 07:18:18 -0000 1.4
+++ libmedia/gst/gstappsink.h 29 Jan 2008 05:18:33 -0000 1.5
@@ -17,7 +17,7 @@
* Boston, MA 02111-1307, USA.
*/
-/* $Id: gstappsink.h,v 1.4 2008/01/27 07:18:18 bjacques Exp $ */
+/* $Id: gstappsink.h,v 1.5 2008/01/29 05:18:33 bjacques Exp $ */
#ifndef _GST_APP_SINK_H_
#define _GST_APP_SINK_H_
@@ -82,6 +82,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);
+GstBuffer * gst_app_sink_pull_buffer_timed (GstAppSink * appsink);
G_END_DECLS
Index: server/parser/video_stream_def.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/video_stream_def.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- server/parser/video_stream_def.cpp 28 Jan 2008 17:20:03 -0000 1.35
+++ server/parser/video_stream_def.cpp 29 Jan 2008 05:18:33 -0000 1.36
@@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
-// $Id: video_stream_def.cpp,v 1.35 2008/01/28 17:20:03 bjacques Exp $
+// $Id: video_stream_def.cpp,v 1.36 2008/01/29 05:18:33 bjacques Exp $
#include "video_stream_def.h"
#include "video_stream_instance.h"
@@ -79,7 +79,7 @@
m_codec_id = static_cast<media::videoCodecType>(in->read_u8());
- _decoder.reset( new media::VideoDecoderGst(m_codec_id) );
+ _decoder.reset( new media::VideoDecoderGst(m_codec_id, _width, _height)
);
}
@@ -104,6 +104,7 @@
GstBuffer* buffer = gst_buffer_new_and_alloc(dataSize+8);
memset(GST_BUFFER_DATA(buffer)+dataSize, 0, 8);
+ GST_BUFFER_SIZE (buffer) = dataSize;
if (!buffer) {
log_error(_("Failed to allocate a buffer of size %d advertised
by SWF."),
@@ -112,16 +113,12 @@
}
GST_BUFFER_OFFSET(buffer) = frameNum;
+ GST_BUFFER_TIMESTAMP(buffer) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
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);
- }
}
@@ -143,18 +140,49 @@
{
// 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));
+ _video_frames.end(), boost::bind(has_frame_number, _1, frameNum));
- if( it == _video_frames.end() )
- {
+ // FIXME: although we return nothing here, we should return the
+ // previously decoded frame.
+ if( it == _video_frames.end() ) {
return std::auto_ptr<image::image_base>();
}
- gst_buffer_ref(*it); // make sure gstreamer doesn't delete the buffer.
+ // We are going backwards, so start from the beginning.
+ if (_last_decoded_frame > boost::int32_t(frameNum)) {
+ _last_decoded_frame = -1;
+ }
+
+ // Push all the frames after the previously decoded frame, until the
+ // target frame has been reached.
+ while (_last_decoded_frame != boost::int32_t(frameNum)) {
+ it = std::find_if(_video_frames.begin(),
+ _video_frames.end(), boost::bind(has_frame_number, _1,
+ _last_decoded_frame));
+
+ if (it == _video_frames.end()) {
+ it = _video_frames.begin();
+ } else {
+ ++it;
+ }
+ if (it == _video_frames.end()) {
+ return std::auto_ptr<image::image_base>();
+ }
+
+ gst_buffer_ref(*it); // make sure gstreamer doesn't delete the
buffer.
+ _last_decoded_frame = GST_BUFFER_OFFSET(*it);
_decoder->pushRawFrame(*it);
+ }
+
+ std::auto_ptr<media::gnashGstBuffer> buffer =
_decoder->popDecodedFrame();
+
+ // If more data has arrived, replace the buffer with the next frame.
+ while (_decoder->peek()) {
+ buffer = _decoder->popDecodedFrame();
+ }
- return std::auto_ptr<image::image_base>(_decoder->popDecodedFrame());
+ return std::auto_ptr<image::image_base>(buffer.release());
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog libmedia/gst/VideoDecoderGst.cp...,
Bastiaan Jacques <=