[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp s...
From: |
Tomas Groth |
Subject: |
[Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp s... |
Date: |
Tue, 23 Jan 2007 16:41:28 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Tomas Groth <tgc> 07/01/23 16:41:28
Modified files:
. : ChangeLog
backend : sound_handler_sdl.cpp
server/asobj : Global.cpp NetConnection.h NetStream.cpp
NetStream.h NetStreamFfmpeg.cpp
NetStreamFfmpeg.h NetStreamGst.cpp
NetStreamGst.h
Log message:
* backend/sound_handler_sdl.cpp: Also resample if samplerate is correct
but number of channels is not (mono => stereo).
* server/asobj/Global.cpp: Initialize NetStream using the new method.
* server/asobj/NetConnection.h: Now compiles without Curl.
* server/asobj/NetStream.{cpp,h}: Initialize NetStream using the new
method.
Implemented the time-property.
* server/asobj/NetStreamFfmpeg.{cpp,h}: Switched from pthreads to boost.
Hopefully fixed a thread-join-bug (#18571).
Use ffmpeg/libavcodec's audio resampler since gnashs own resampler
only
supports a limited samplerates.
Implemented seek() and time().
* server/asobj/NetStreamGst.{cpp,h}: Implemented seek() and time().
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2155&r2=1.2156
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/sound_handler_sdl.cpp?cvsroot=gnash&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Global.cpp?cvsroot=gnash&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetConnection.h?cvsroot=gnash&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.cpp?cvsroot=gnash&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStream.h?cvsroot=gnash&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.cpp?cvsroot=gnash&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamFfmpeg.h?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/NetStreamGst.h?cvsroot=gnash&r1=1.3&r2=1.4
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2155
retrieving revision 1.2156
diff -u -b -r1.2155 -r1.2156
--- ChangeLog 23 Jan 2007 12:40:21 -0000 1.2155
+++ ChangeLog 23 Jan 2007 16:41:27 -0000 1.2156
@@ -1,3 +1,18 @@
+2007-01-23 Tomas Groth Christensen <address@hidden>
+
+ * backend/sound_handler_sdl.cpp: Also resample if samplerate is correct
+ but number of channels is not (mono => stereo).
+ * server/asobj/Global.cpp: Initialize NetStream using the new method.
+ * server/asobj/NetConnection.h: Now compiles without Curl.
+ * server/asobj/NetStream.{cpp,h}: Initialize NetStream using the new
method.
+ Implemented the time-property.
+ * server/asobj/NetStreamFfmpeg.{cpp,h}: Switched from pthreads to boost.
+ Hopefully fixed a thread-join-bug (#18571).
+ Use ffmpeg/libavcodec's audio resampler since gnashs own resampler
only
+ supports a limited samplerates.
+ Implemented seek() and time().
+ * server/asobj/NetStreamGst.{cpp,h}: Implemented seek() and time().
+
2007-01-23 Sandro Santilli <address@hidden>
* testsuite/actionscript.all/: Inheritance.as, MovieClip.as:
Index: backend/sound_handler_sdl.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/sound_handler_sdl.cpp,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- backend/sound_handler_sdl.cpp 18 Jan 2007 11:53:37 -0000 1.43
+++ backend/sound_handler_sdl.cpp 23 Jan 2007 16:41:27 -0000 1.44
@@ -18,7 +18,7 @@
// Based on sound_handler_sdl.cpp by Thatcher Ulrich http://tulrich.com 2003
// which has been donated to the Public Domain.
-// $Id: sound_handler_sdl.cpp,v 1.43 2007/01/18 11:53:37 tgc Exp $
+// $Id: sound_handler_sdl.cpp,v 1.44 2007/01/23 16:41:27 tgc Exp $
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -942,8 +942,8 @@
}
#endif
- // If we need to convert samplerate...
- if (outsize > 0 &&
sounddata->sample_rate != handler->audioSpec.freq) {
+ // If we need to convert samplerate
or/and from mono to stereo...
+ if (outsize > 0 &&
(sounddata->sample_rate != handler->audioSpec.freq || !sounddata->stereo)) {
int16_t* adjusted_data = 0;
int adjusted_size = 0;
Index: server/asobj/Global.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Global.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- server/asobj/Global.cpp 18 Jan 2007 22:53:21 -0000 1.33
+++ server/asobj/Global.cpp 23 Jan 2007 16:41:27 -0000 1.34
@@ -18,7 +18,7 @@
// Implementation of the Global ActionScript Object
-/* $Id: Global.cpp,v 1.33 2007/01/18 22:53:21 strk Exp $ */
+/* $Id: Global.cpp,v 1.34 2007/01/23 16:41:27 tgc Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -497,7 +497,7 @@
//-----------------------
init_member("NetConnection", as_value(netconnection_new));
- init_member("NetStream", as_value(netstream_new));
+ netstream_class_init(*this);
contextmenu_class_init(*this);
moviecliploader_class_init(*this);
// sephiroth.it refers this to be introduced in SWF7
Index: server/asobj/NetConnection.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetConnection.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- server/asobj/NetConnection.h 18 Jan 2007 11:53:37 -0000 1.12
+++ server/asobj/NetConnection.h 23 Jan 2007 16:41:27 -0000 1.13
@@ -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: NetConnection.h,v 1.12 2007/01/18 11:53:37 tgc Exp $ */
+/* $Id: NetConnection.h,v 1.13 2007/01/23 16:41:27 tgc Exp $ */
#ifndef __NETCONNECTION_H__
#define __NETCONNECTION_H__
@@ -121,7 +121,9 @@
public:
NetConnection() {};
~NetConnection() {};
- bool openConnection(const char* /*char_url*/, as_object* /*ns*/) {
return false; };
+ bool openConnection(const char* /*char_url*/, as_object* /*ns*/, bool
/* local */) { return false; };
+ bool seek(size_t /*pos*/) { return 0; }
+ size_t read(void* /*dst*/, size_t /*bytes*/) { return false; }
};
#endif // HAVE_CURL_CURL_H
@@ -130,10 +132,6 @@
{
public:
NetConnection obj;
- /*void seek(int pos) { obj.seek(pos); }
- void read(void* buf, int buf_size) {
obj.read(static_cast<uint8_t*>(buf), buf_size); }
- void openConnection(as_object* ns, const char* url) {
obj.openConnection(url, ns); }
- int getFD() { return obj.getFD(); }*/
};
DSOEXPORT void netconnection_new(const fn_call& fn);
Index: server/asobj/NetStream.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.cpp,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- server/asobj/NetStream.cpp 18 Jan 2007 22:53:21 -0000 1.22
+++ server/asobj/NetStream.cpp 23 Jan 2007 16:41:27 -0000 1.23
@@ -18,7 +18,7 @@
//
//
-/* $Id: NetStream.cpp,v 1.22 2007/01/18 22:53:21 strk Exp $ */
+/* $Id: NetStream.cpp,v 1.23 2007/01/23 16:41:27 tgc Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -27,31 +27,37 @@
#include "log.h"
#include "NetStream.h"
#include "fn_call.h"
+#include "builtin_function.h"
#include "movie_root.h"
-#if defined(_WIN32) || defined(WIN32)
- #include <Windows.h> // for sleep()
- #define usleep(x) Sleep(x/1000)
-#else
- #include "unistd.h" // for usleep()
-#endif
-
namespace gnash {
-void
-netstream_new(const fn_call& fn)
+static void netstream_new(const fn_call& fn);
+static void netstream_close(const fn_call& fn);
+static void netstream_pause(const fn_call& fn);
+static void netstream_play(const fn_call& fn);
+static void netstream_seek(const fn_call& fn);
+static void netstream_setbuffertime(const fn_call& fn);
+static void netstream_time(const fn_call& fn);
+static as_object* getNetStreamInterface();
+
+netstream_as_object::netstream_as_object()
+ :
+ as_object(getNetStreamInterface())
{
- netstream_as_object *netstream_obj = new netstream_as_object;
+ obj.set_parent(this);
+}
+
+netstream_as_object::~netstream_as_object()
+{
+}
- // FIXME: rely on inheritance
- netstream_obj->init_member("close", &netstream_close);
- netstream_obj->init_member("pause", &netstream_pause);
- netstream_obj->init_member("play", &netstream_play);
- netstream_obj->init_member("seek", &netstream_seek);
- netstream_obj->init_member("setBufferTime", &netstream_setbuffertime);
+static void
+netstream_new(const fn_call& fn)
+{
- fn.result->set_as_object(netstream_obj);
+ netstream_as_object *netstream_obj = new netstream_as_object;
if (fn.nargs > 0)
{
@@ -67,17 +73,19 @@
);
}
}
+ fn.result->set_as_object(netstream_obj);
}
-void netstream_close(const fn_call& fn)
+
+static void netstream_close(const fn_call& fn)
{
assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
netstream_as_object* ns =
static_cast<netstream_as_object*>(fn.this_ptr);
ns->obj.close();
}
-void netstream_pause(const fn_call& fn)
+static void netstream_pause(const fn_call& fn)
{
assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
netstream_as_object* ns =
static_cast<netstream_as_object*>(fn.this_ptr);
@@ -91,7 +99,7 @@
ns->obj.pause(mode); // toggle mode
}
-void netstream_play(const fn_call& fn)
+static void netstream_play(const fn_call& fn)
{
assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
netstream_as_object* ns =
static_cast<netstream_as_object*>(fn.this_ptr);
@@ -108,12 +116,95 @@
};
}
-void netstream_seek(const fn_call& /*fn*/) {
- log_msg("%s:unimplemented \n", __FUNCTION__);
+static void netstream_seek(const fn_call& fn) {
+ assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
+ netstream_as_object* ns =
static_cast<netstream_as_object*>(fn.this_ptr);
+
+ double time = 0;
+ if (fn.nargs > 0)
+ {
+ time = fn.arg(0).to_number();
+ }
+ ns->obj.seek(time);
+
}
-void netstream_setbuffertime(const fn_call& /*fn*/) {
+static void netstream_setbuffertime(const fn_call& /*fn*/) {
log_msg("%s:unimplemented \n", __FUNCTION__);
}
+// Both a getter and a (do-nothing) setter for time
+static void
+netstream_time(const fn_call& fn)
+{
+
+ assert(dynamic_cast<netstream_as_object*>(fn.this_ptr));
+ netstream_as_object* ns =
static_cast<netstream_as_object*>(fn.this_ptr);
+
+ if ( fn.nargs == 0 )
+ {
+ fn.result->set_double((double)ns->obj.time());
+ }
+ else
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Tried to set read-only property
NetStream.time");
+ );
+ }
+}
+
+void
+attachNetStreamInterface(as_object& o)
+{
+
+ o.init_member("close", &netstream_close);
+ o.init_member("pause", &netstream_pause);
+ o.init_member("play", &netstream_play);
+ o.init_member("seek", &netstream_seek);
+ o.init_member("setBufferTime", &netstream_setbuffertime);
+
+
+ // Properties
+
+ boost::intrusive_ptr<builtin_function> gettersetter;
+
+ gettersetter = new builtin_function(&netstream_time, NULL);
+ o.init_property("time", *gettersetter, *gettersetter);
+
+}
+
+static as_object*
+getNetStreamInterface()
+{
+
+ static boost::intrusive_ptr<as_object> o;
+ if ( o == NULL )
+ {
+ o = new as_object();
+ attachNetStreamInterface(*o);
+ }
+
+ return o.get();
+}
+
+// extern (used by Global.cpp)
+void netstream_class_init(as_object& global)
+{
+
+ // This is going to be the global NetStream "class"/"function"
+ static boost::intrusive_ptr<builtin_function> cl;
+
+ if ( cl == NULL )
+ {
+ cl=new builtin_function(&netstream_new,
getNetStreamInterface());
+ // replicate all interface to class, to be able to access
+ // all methods as static functions
+ attachNetStreamInterface(*cl);
+
+ }
+
+ // Register _global.String
+ global.init_member("NetStream", cl.get());
+
+}
} // end of gnash namespace
Index: server/asobj/NetStream.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStream.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- server/asobj/NetStream.h 18 Jan 2007 22:53:21 -0000 1.17
+++ server/asobj/NetStream.h 23 Jan 2007 16:41:28 -0000 1.18
@@ -18,7 +18,7 @@
//
//
-/* $Id: NetStream.h,v 1.17 2007/01/18 22:53:21 strk Exp $ */
+/* $Id: NetStream.h,v 1.18 2007/01/23 16:41:28 tgc Exp $ */
#ifndef __NETSTREAM_H__
#define __NETSTREAM_H__
@@ -45,11 +45,12 @@
void close(){}
void pause(int /*mode*/){}
int play(const char* /*source*/){ log_error("FFMPEG or Gstreamer is
needed to play video"); return 0; }
- void seek(unsigned int /*pos*/){}
+ void seek(double /*pos*/){}
void setBufferTime(unsigned int /*pos*/){}
void set_status(const char* /*code*/){}
void setNetCon(as_object* /*nc*/) {}
image::image_base* get_video(){ return NULL; }
+ long time() { return 0; }
inline void set_parent(netstream_as_object* /*ns*/)
{
@@ -77,25 +78,16 @@
{
public:
- netstream_as_object()
- {
- obj.set_parent(this);
- }
+ netstream_as_object();
- ~netstream_as_object()
- {
- }
+ ~netstream_as_object();
NetStream obj;
};
-void netstream_new(const fn_call& fn);
-void netstream_close(const fn_call& fn);
-void netstream_pause(const fn_call& fn);
-void netstream_play(const fn_call& fn);
-void netstream_seek(const fn_call& fn);
-void netstream_setbuffertime(const fn_call& fn);
+// Initialize the global NetStream class
+void netstream_class_init(as_object& global);
} // end of gnash namespace
Index: server/asobj/NetStreamFfmpeg.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- server/asobj/NetStreamFfmpeg.cpp 18 Jan 2007 22:53:21 -0000 1.7
+++ server/asobj/NetStreamFfmpeg.cpp 23 Jan 2007 16:41:28 -0000 1.8
@@ -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: NetStreamFfmpeg.cpp,v 1.7 2007/01/18 22:53:21 strk Exp $ */
+/* $Id: NetStreamFfmpeg.cpp,v 1.8 2007/01/23 16:41:28 tgc Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -54,6 +54,7 @@
m_ACodecCtx(NULL),
m_FormatCtx(NULL),
m_Frame(NULL),
+ m_Resample(NULL),
m_go(false),
m_imageframe(NULL),
@@ -99,7 +100,11 @@
m_go = false;
// wait till thread is complete before main continues
- pthread_join(m_thread, NULL);
+ m_thread->join();
+ if (m_thread) delete m_thread;
+ }
+ if (startThread) {
+ delete startThread;
}
// When closing gnash before playback is finished, the soundhandler
@@ -119,9 +124,15 @@
if (m_ACodecCtx) avcodec_close(m_ACodecCtx);
m_ACodecCtx = NULL;
+ if (m_FormatCtx) {
m_FormatCtx->iformat->flags = AVFMT_NOFILE;
- if (m_FormatCtx) av_close_input_file(m_FormatCtx);
+ av_close_input_file(m_FormatCtx);
m_FormatCtx = NULL;
+ }
+
+ if (m_Resample) {
+ audio_resample_close (m_Resample);
+ }
if (m_imageframe) delete m_imageframe;
@@ -137,8 +148,6 @@
m_qaudio.pop();
}
- //delete input;
-
}
// ffmpeg callback function
@@ -199,17 +208,19 @@
m_go = true;
// To avoid blocking while connecting, we use a thread.
- if (pthread_create(&startThread, NULL, NetStreamFfmpeg::startPlayback,
this) != 0)
- {
- return 0;
- };
+ startThread = new
boost::thread(boost::bind(NetStreamFfmpeg::startPlayback, this));
+
+ // This starts the decoding thread
+ lock = new boost::mutex::scoped_lock(start_mutex);
+ m_thread = new boost::thread(boost::bind(NetStreamFfmpeg::av_streamer,
this));
+
return 0;
}
-void*
-NetStreamFfmpeg::startPlayback(void* arg)
+void
+NetStreamFfmpeg::startPlayback(NetStreamFfmpeg* ns)
{
- NetStreamFfmpeg* ns = static_cast<NetStreamFfmpeg*>(arg);
+
netconnection_as_object* nc =
static_cast<netconnection_as_object*>(ns->netCon);
URL uri(ns->url);
@@ -262,7 +273,7 @@
if(av_open_input_stream(&ns->m_FormatCtx, &ns->ByteIOCxt, "", inputFmt,
NULL) < 0){
log_error("Couldn't open file '%s' for decoding",
ns->url.c_str());
ns->set_status("NetStream.Play.StreamNotFound");
- return 0;
+ return;
}
// Next, we need to retrieve information about the streams contained in
the file
@@ -271,7 +282,7 @@
if (ret < 0)
{
log_error("Couldn't find stream information from '%s', error
code: %d", ns->url.c_str(), ret);
- return 0;
+ return;
}
// m_FormatCtx->pb.eof_reached = 0;
@@ -280,7 +291,7 @@
// Find the first video & audio stream
ns->m_video_index = -1;
ns->m_audio_index = -1;
- for (int i = 0; i < ns->m_FormatCtx->nb_streams; i++)
+ for (unsigned int i = 0; i < ns->m_FormatCtx->nb_streams; i++)
{
AVCodecContext* enc = ns->m_FormatCtx->streams[i]->codec;
@@ -311,7 +322,7 @@
if (ns->m_video_index < 0)
{
log_error("Didn't find a video stream from '%s'",
ns->url.c_str());
- return 0;
+ return;
}
// Get a pointer to the codec context for the video stream
@@ -323,7 +334,7 @@
{
ns->m_VCodecCtx = NULL;
log_error("Decoder not found");
- return 0;
+ return;
}
// Open codec
@@ -355,14 +366,14 @@
if(pACodec == NULL)
{
log_error("No available AUDIO decoder to process MPEG
file: '%s'", ns->url.c_str());
- return 0;
+ return;
}
// Open codec
if (avcodec_open(ns->m_ACodecCtx, pACodec) < 0)
{
log_error("Could not open AUDIO codec");
- return 0;
+ return;
}
s->attach_aux_streamer(audio_streamer, (void*) ns);
@@ -371,11 +382,9 @@
ns->m_pause = false;
- if (pthread_create(&ns->m_thread, NULL, NetStreamFfmpeg::av_streamer,
ns) != 0)
- {
- return 0;
- };
- return 0;
+ // By deleting this lock we allow the av_streamer-thread to start its
work
+ delete ns->lock;
+ return;
}
void
@@ -384,9 +393,11 @@
}
// decoder thread
-void* NetStreamFfmpeg::av_streamer(void* arg)
+void NetStreamFfmpeg::av_streamer(NetStreamFfmpeg* ns)
{
- NetStreamFfmpeg* ns = static_cast<NetStreamFfmpeg*>(arg);
+
+ boost::mutex::scoped_lock lock(ns->start_mutex);
+
ns->set_status("NetStream.Play.Start");
raw_videodata_t* video = NULL;
@@ -397,6 +408,7 @@
ns->m_start_clock = tu_timer::ticks_to_seconds(tu_timer::get_ticks());
ns->m_go = true;
ns->m_unqueued_data = NULL;
+
while (ns->m_go)
{
if (ns->m_pause)
@@ -449,8 +461,7 @@
}
}
ns->set_status("NetStream.Play.Stop");
- pthread_exit(0);
- return 0;
+
}
// audio callback is running in sound handler thread
@@ -458,6 +469,8 @@
{
NetStreamFfmpeg* ns = static_cast<NetStreamFfmpeg*>(owner);
+ boost::mutex::scoped_lock lock(ns->decoding_mutex);
+
while (len > 0 && ns->m_qaudio.size() > 0)
{
raw_videodata_t* samples = ns->m_qaudio.front();
@@ -479,6 +492,8 @@
bool NetStreamFfmpeg::read_frame()
{
+ boost::mutex::scoped_lock lock(decoding_mutex);
+
// raw_videodata_t* ret = NULL;
if (m_unqueued_data)
{
@@ -517,19 +532,22 @@
if (avcodec_decode_audio(m_ACodecCtx,
(int16_t*) ptr, &frame_size, packet.data, packet.size) >= 0)
{
- int16_t* adjusted_data = 0;
- int n = 0;
-
bool stereo = m_ACodecCtx->channels > 1
? true : false;
int samples = stereo ? frame_size >> 2
: frame_size >> 1;
- // This convertion only works for 5.5,
11, 22 and 44 KHz. 32KHz causes problems.
- s->convert_raw_data(&adjusted_data, &n,
ptr, samples, 2, m_ACodecCtx->sample_rate, stereo);
+ // Resampeling using ffmpegs
(libavcodecs) resampler
+ if (!m_Resample) {
+ // arguments: (output channels,
input channels, output rate, input rate)
+ m_Resample =
audio_resample_init (2, m_ACodecCtx->channels, 44100, m_ACodecCtx->sample_rate);
+ }
+ // The size of this is a guess, we
don't know yet... Lets hope it's big enough
+ int16_t* output_data = new
int16_t[frame_size * 2];
+ samples = audio_resample (m_Resample,
output_data, (int16_t*)ptr, samples);
raw_videodata_t* raw = new
raw_videodata_t;
- raw->m_data = (uint8_t*) adjusted_data;
+ raw->m_data = (uint8_t*) output_data;
raw->m_ptr = raw->m_data;
- raw->m_size = n;
+ raw->m_size = samples * 2 * 2; // 2 for
stereo and 2 for samplesize = 2 bytes
raw->m_stream_index = m_audio_index;
m_unqueued_data = m_qaudio.push(raw) ?
NULL : raw;
@@ -637,6 +655,7 @@
}
else
{
+ log_warning("Problems decoding frame");
return false;
}
@@ -649,9 +668,58 @@
}
void
-NetStreamFfmpeg::seek()
+NetStreamFfmpeg::seek(double pos)
{
- log_msg("%s:unimplemented \n", __FUNCTION__);
+ boost::mutex::scoped_lock lock(decoding_mutex);
+
+ // Seek to new position
+ double timebase =
(double)m_FormatCtx->streams[m_video_index]->time_base.num /
(double)m_FormatCtx->streams[m_video_index]->time_base.den;
+
+ long newpos = (long)(pos / timebase);
+
+ if (av_seek_frame(m_FormatCtx, m_video_index, newpos, 0) < 0) {
+ log_warning("seeking failed");
+ return;
+ }
+
+ // This is kindof hackish and ugly :-(
+ if (newpos == 0) {
+ m_video_clock = 0;
+ m_start_clock =
tu_timer::ticks_to_seconds(tu_timer::get_ticks());
+ } else {
+
+ AVPacket Packet;
+ av_init_packet(&Packet);
+ double newtime = 0;
+ while (newtime == 0) {
+ if ( av_read_frame(m_FormatCtx, &Packet) < 0) {
+ av_seek_frame(m_FormatCtx, -1,
0,AVSEEK_FLAG_BACKWARD);
+ av_free_packet(&Packet);
+ return;
+ }
+
+ newtime = timebase *
(double)m_FormatCtx->streams[m_video_index]->cur_dts;
+ }
+
+ av_free_packet(&Packet);
+ av_seek_frame(m_FormatCtx, m_video_index, newpos, 0);
+
+ m_start_clock += m_video_clock - newtime;
+
+ m_video_clock = newtime;
+ }
+ // Flush the queues
+ while (m_qvideo.size() > 0)
+ {
+ delete m_qvideo.front();
+ m_qvideo.pop();
+ }
+
+ while (m_qaudio.size() > 0)
+ {
+ delete m_qaudio.front();
+ m_qaudio.pop();
+ }
}
void
@@ -660,6 +728,17 @@
log_msg("%s:unimplemented \n", __FUNCTION__);
}
+long
+NetStreamFfmpeg::time()
+{
+ if (m_FormatCtx && m_FormatCtx->nb_streams > 0) {
+ double time = (double)m_FormatCtx->streams[0]->time_base.num /
(double)m_FormatCtx->streams[0]->time_base.den *
(double)m_FormatCtx->streams[0]->cur_dts;
+ return (long) time;
+ } else {
+ return 0;
+ }
+}
+
} // gnash namespcae
#endif // USE_FFMPEG
Index: server/asobj/NetStreamFfmpeg.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamFfmpeg.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/asobj/NetStreamFfmpeg.h 18 Jan 2007 11:53:37 -0000 1.3
+++ server/asobj/NetStreamFfmpeg.h 23 Jan 2007 16:41:28 -0000 1.4
@@ -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: NetStreamFfmpeg.h,v 1.3 2007/01/18 11:53:37 tgc Exp $ */
+/* $Id: NetStreamFfmpeg.h,v 1.4 2007/01/23 16:41:28 tgc Exp $ */
#ifndef __NETSTREAMFFMPEG_H__
#define __NETSTREAMFFMPEG_H__
@@ -26,7 +26,11 @@
#ifdef USE_FFMPEG
#include <queue>
-#include <pthread.h>
+//#include <pthread.h>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+
#include "impl.h"
#include "video_stream_instance.h"
#include <ffmpeg/avformat.h>
@@ -153,10 +157,11 @@
void close();
void pause(int mode);
int play(const char* source);
- void seek();
+ void seek(double pos);
void setBufferTime();
void set_status(const char* code);
void setNetCon(as_object* nc);
+ long time();
// Used for ffmpeg data read and seek callbacks
static int readPacket(void* opaque, uint8_t* buf, int buf_size);
@@ -181,8 +186,8 @@
return time.num / (double) time.den;
}
- static void* startPlayback(void* arg);
- static void* av_streamer(void* arg);
+ static void startPlayback(NetStreamFfmpeg* ns);
+ static void av_streamer(NetStreamFfmpeg* ns);
static void audio_streamer(void *udata, uint8 *stream, int len);
private:
@@ -210,6 +215,8 @@
AVFrame* m_Frame;
+ ReSampleContext *m_Resample;
+
volatile bool m_go;
unsigned int runtime;
@@ -217,8 +224,14 @@
double m_video_clock;
- pthread_t m_thread;
- pthread_t startThread;
+// pthread_t m_thread;
+// pthread_t startThread;
+ boost::thread *m_thread;
+ boost::thread *startThread;
+ boost::mutex decoding_mutex;
+ boost::mutex start_mutex;
+ boost::mutex::scoped_lock *lock;
+
multithread_queue <raw_videodata_t*> m_qaudio;
multithread_queue <raw_videodata_t*> m_qvideo;
bool m_pause;
Index: server/asobj/NetStreamGst.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/asobj/NetStreamGst.cpp 18 Jan 2007 22:53:21 -0000 1.4
+++ server/asobj/NetStreamGst.cpp 23 Jan 2007 16:41:28 -0000 1.5
@@ -35,26 +35,29 @@
#include "URL.h"
-#if defined(_WIN32) || defined(WIN32)
- #include <Windows.h> // for sleep()
- #define usleep(x) Sleep(x/1000)
-#else
- #include "unistd.h" // for usleep()
-#endif
-
-
-
namespace gnash {
NetStreamGst::NetStreamGst():
+ pipeline(NULL),
+ audiosink(NULL),
+ videosink(NULL),
+ source(NULL),
+ decoder(NULL),
+ volume(NULL),
+ colorspace(NULL),
+ videorate(NULL),
+ videocaps(NULL),
+ videoflip(NULL),
+ audioconv(NULL),
m_go(false),
m_imageframe(NULL),
m_pause(false),
inputPos(0),
videowidth(0),
videoheight(0)
+
{
}
@@ -317,27 +320,23 @@
// Setup the videorate element which makes sure the frames are
delivered on time.
ns->videorate = gst_element_factory_make ("videorate", NULL);
- // Setup the videorate element which makes sure the frames are
delivered on time.
-/* ns->videoflip = gst_element_factory_make ("videoflip", NULL);
- g_object_set (G_OBJECT (ns->videoflip), "method", 5, NULL);*/
-
// setup the videosink with callback
ns->videosink = gst_element_factory_make ("fakesink", NULL);
g_object_set (G_OBJECT (ns->videosink), "signal-handoffs", TRUE,
"sync", TRUE, NULL);
g_signal_connect (ns->videosink, "handoff", G_CALLBACK
(NetStreamGst::callback_output), ns);
- if (!ns->source || !ns->audioconv || !ns->volume || !ns->decoder ||
!ns->colorspace /*|| !ns->videoflip*/ || !ns->videocaps || !ns->videorate ||
!ns->videosink) {
+ if (!ns->source || !ns->audioconv || !ns->volume || !ns->decoder ||
!ns->colorspace || !ns->videocaps || !ns->videorate || !ns->videosink) {
gnash::log_error("Gstreamer element(s) for movie handling could
not be created\n");
return 0;
}
// put it all in the pipeline
- gst_bin_add_many (GST_BIN (ns->pipeline), ns->source, ns->decoder,
ns->audiosink, ns->audioconv, ns->colorspace, ns->videosink, ns->videorate,
ns->videocaps, /*ns->videoflip,*/ ns->volume, NULL);
+ gst_bin_add_many (GST_BIN (ns->pipeline), ns->source, ns->decoder,
ns->audiosink, ns->audioconv, ns->colorspace, ns->videosink, ns->videorate,
ns->videocaps, ns->volume, NULL);
// link the elements
gst_element_link(ns->source, ns->decoder);
gst_element_link_many(ns->audioconv, ns->volume, ns->audiosink, NULL);
- gst_element_link_many(/*ns->videoflip,*/ ns->colorspace, ns->videocaps,
ns->videorate, ns->videosink, NULL);
+ gst_element_link_many(ns->colorspace, ns->videocaps, ns->videorate,
ns->videosink, NULL);
// start playing
gst_element_set_state (ns->pipeline, GST_STATE_PLAYING);
@@ -355,9 +354,12 @@
}
void
-NetStreamGst::seek()
+NetStreamGst::seek(double pos)
{
- log_msg("%s:unimplemented \n", __FUNCTION__);
+
+ if (!gst_element_seek_simple(pipeline, GST_FORMAT_TIME,
GST_SEEK_FLAG_KEY_UNIT, GST_SECOND * static_cast<long>(pos))) {
+ log_warning("seek failed");
+ }
}
void
@@ -366,6 +368,29 @@
log_msg("%s:unimplemented \n", __FUNCTION__);
}
+long
+NetStreamGst::time()
+{
+
+ if (!pipeline) return 0;
+
+ GstFormat fmt = GST_FORMAT_TIME;
+ long pos;
+ GstStateChangeReturn ret;
+ GstState current, pending;
+
+ ret = gst_element_get_state (GST_ELEMENT (pipeline), ¤t,
&pending, 0);
+// fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not changing state async");
+// fail_unless (current == GST_STATE_READY, "bad current state");
+// fail_unless (pending == GST_STATE_PLAYING, "bad pending state");
+
+ if (current != GST_STATE_NULL && gst_element_query_position (pipeline,
&fmt, &pos)) {
+ return pos;
+ } else {
+ return 0;
+ }
+}
+
// Gstreamer callback function
int
NetStreamGst::readPacket(void* opaque, char* buf, int buf_size){
Index: server/asobj/NetStreamGst.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/NetStreamGst.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/asobj/NetStreamGst.h 15 Jan 2007 20:58:53 -0000 1.3
+++ server/asobj/NetStreamGst.h 23 Jan 2007 16:41:28 -0000 1.4
@@ -42,10 +42,11 @@
void close();
void pause(int mode);
int play(const char* source);
- void seek();
+ void seek(double pos);
void setBufferTime();
void set_status(const char* code);
void setNetCon(as_object* nc);
+ long time();
// Used for gstreamer data read and seek callbacks
static int readPacket(void* opaque, char* buf, int buf_size);
- [Gnash-commit] gnash ChangeLog backend/sound_handler_sdl.cpp s...,
Tomas Groth <=