gnash-commit
[Top][All Lists]
Advanced

[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());
 }
 
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]