[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10503: Remove libmedia dependency o
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10503: Remove libmedia dependency on libcore. Fix metadata handling crash |
Date: |
Sat, 03 Jan 2009 17:45:59 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10503
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sat 2009-01-03 17:45:59 +0100
message:
Remove libmedia dependency on libcore. Fix metadata handling crash
(bug #22868). Minor modifications, with documentation, to libmedia interface
and removal of VM functionality to libcore.
modified:
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/Date_as.cpp
libcore/asobj/Date_as.h
libcore/asobj/NetConnection_as.cpp
libcore/asobj/NetStream_as.cpp
libcore/asobj/SharedObject_as.cpp
libcore/parser/action_buffer.h
libmedia/AudioDecoderNellymoser.cpp
libmedia/FLVParser.cpp
libmedia/FLVParser.h
libmedia/Makefile.am
libmedia/MediaHandler.cpp
libmedia/MediaHandler.h
libmedia/MediaParser.cpp
libmedia/MediaParser.h
libmedia/ffmpeg/MediaHandlerFfmpeg.cpp
libmedia/ffmpeg/MediaParserFfmpeg.cpp
libmedia/gst/MediaHandlerGst.cpp
------------------------------------------------------------
revno: 10502.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2009-01-02 16:37:21 +0100
message:
Minor cleanups.
modified:
libcore/as_value.cpp
------------------------------------------------------------
revno: 10502.1.2
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Fri 2009-01-02 17:08:00 +0100
message:
Drop stuff.
modified:
libcore/parser/action_buffer.h
------------------------------------------------------------
revno: 10502.1.3
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 09:45:20 +0100
message:
Rearrange header.
modified:
libmedia/FLVParser.h
------------------------------------------------------------
revno: 10502.1.4
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 10:37:30 +0100
message:
Line breaks.
modified:
libcore/asobj/NetStream_as.cpp
------------------------------------------------------------
revno: 10502.1.5
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 10:54:35 +0100
message:
Have isFLV throw an IOException when not enough bytes are available for
reading. Add exception specification, document and catch it. Throw
MediaException not GnashException on other libmedia errors.
Split long lines.
modified:
libmedia/FLVParser.cpp
libmedia/FLVParser.h
libmedia/MediaHandler.cpp
libmedia/MediaHandler.h
libmedia/ffmpeg/MediaHandlerFfmpeg.cpp
libmedia/ffmpeg/MediaParserFfmpeg.cpp
libmedia/gst/MediaHandlerGst.cpp
------------------------------------------------------------
revno: 10502.1.6
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 16:01:27 +0100
message:
Replace MetaTag struct with a simple multimap of timestamp to buffer.
Transfer
tags to NetStream_as before executing, and move execution to libcore
instead
of libmedia. This removes libmedia's dependency on libcore for this
purpose,
and more importantly fixes a crash when a metadata function triggers the
destruction of the FLVParser.
Make readAMF0 const correct, update all callers.
Register Date prototype with VM using addStatic, which fixes a crash in
AMF parsing (Date construction).
Don't use the VM's RNG in AudioDecoderNellymoser. It's not thread-safe,
and
creates an unnecessary dependency.
Remove libmedia's dependency on libcore for win32 (should now build
without).
modified:
libcore/as_value.cpp
libcore/as_value.h
libcore/asobj/Date_as.cpp
libcore/asobj/Date_as.h
libcore/asobj/NetConnection_as.cpp
libcore/asobj/NetStream_as.cpp
libcore/asobj/SharedObject_as.cpp
libmedia/AudioDecoderNellymoser.cpp
libmedia/FLVParser.cpp
libmedia/FLVParser.h
libmedia/Makefile.am
libmedia/MediaParser.cpp
libmedia/MediaParser.h
------------------------------------------------------------
revno: 10502.1.7
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 16:29:43 +0100
message:
Dox, quieten debugging.
modified:
libcore/as_value.cpp
libcore/asobj/NetStream_as.cpp
libmedia/FLVParser.h
libmedia/MediaParser.h
------------------------------------------------------------
revno: 10502.1.8
committer: Benjamin Wolsey <address@hidden>
branch nick: test
timestamp: Sat 2009-01-03 17:34:08 +0100
message:
Move typedefs to MediaParser class.
modified:
libcore/asobj/NetStream_as.cpp
libmedia/MediaParser.h
=== modified file 'libcore/as_value.cpp'
--- a/libcore/as_value.cpp 2009-01-02 12:48:38 +0000
+++ b/libcore/as_value.cpp 2009-01-03 15:29:43 +0000
@@ -58,7 +58,7 @@
// Define this macro to make soft references activity verbose
//#define GNASH_DEBUG_SOFT_REFERENCES
-// Define this macto to make AMF parsing verbose
+// Define this macro to make AMF parsing verbose
//#define GNASH_DEBUG_AMF_DESERIALIZE
// Define this macto to make AMF writing verbose
@@ -437,13 +437,6 @@
hint = STRING;
}
-#if 0
- else if ( m_type == MOVIECLIP && swfVersion > 5 )
- {
- throw ActionTypeError();
- }
-#endif
-
return convert_to_primitive(hint);
}
@@ -452,7 +445,6 @@
as_value::to_primitive(AsType hint) const
{
if ( m_type != OBJECT && m_type != AS_FUNCTION ) return *this;
- //if ( ! is_object() ) return *this; // include MOVIECLIP !!
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug("to_primitive(%s)", hint==NUMBER ? "NUMBER" : "STRING");
@@ -490,12 +482,10 @@
{
assert(hint==STRING);
-#if 1
if ( m_type == MOVIECLIP )
{
return as_value(getCharacterProxy().getTarget());
}
-#endif
if ( m_type == OBJECT ) obj = getObj().get();
else obj = getFun().get();
@@ -516,17 +506,18 @@
return as_value(obj->get_text_value());
}
- if ( (!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
(!method.is_function()) ) // ECMA says ! is_object()
+ if ( (!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
+ (!method.is_function()) ) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" toString not found");
#endif
- if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
(!method.is_function()) ) // ECMA says ! is_object()
+ if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
+ (!method.is_function()) ) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" valueOf not found");
#endif
- //return as_value(obj->get_text_value());
throw ActionTypeError();
}
}
@@ -575,7 +566,8 @@
if ( m_type == OBJECT ) obj = getObj().get();
else obj = getFun().get();
- if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
(!method.is_object()) ) // ECMA says ! is_object()
+ if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
+ (!method.is_object()) ) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" valueOf not found");
@@ -619,12 +611,14 @@
return *this;
}
- if ( (!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
(!method.is_function()) ) // ECMA says ! is_object()
+ if ( (!obj->get_member(NSV::PROP_TO_STRING, &method)) ||
+ (!method.is_function()) ) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" toString not found");
#endif
- if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
(!method.is_function()) ) // ECMA says ! is_object()
+ if ( (!obj->get_member(NSV::PROP_VALUE_OF, &method)) ||
+ (!method.is_function()) ) // ECMA says ! is_object()
{
#if GNASH_DEBUG_CONVERSION_TO_PRIMITIVE
log_debug(" valueOf not found");
@@ -654,7 +648,6 @@
double
as_value::to_number() const
{
- // TODO: split in to_number_# (version based)
int swfversion = VM::get().getSWFVersion();
@@ -2110,7 +2103,7 @@
// TODO restore first parameter on parse errors
//
static bool
-amf0_read_value(boost::uint8_t *&b, boost::uint8_t *end,
+amf0_read_value(const boost::uint8_t *&b, const boost::uint8_t *end,
as_value& ret, int inType, std::vector<as_object*>& objRefs, VM& vm)
{
int amf_type;
@@ -2176,7 +2169,7 @@
}
{
- std::string str(reinterpret_cast<char *>(b),
si); b += si;
+ std::string str(reinterpret_cast<const
char*>(b), si); b += si;
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
log_debug("amf0 read string: %s", str);
#endif
@@ -2202,7 +2195,7 @@
}
{
- std::string str(reinterpret_cast<char *>(b),
si); b += si;
+ std::string str(reinterpret_cast<const
char*>(b), si); b += si;
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
log_debug("amf0 read long string: %s", str);
#endif
@@ -2284,7 +2277,7 @@
break;
}
- std::string
name(reinterpret_cast<char*>(b), strlen);
+ std::string name(reinterpret_cast<const
char*>(b), strlen);
#ifdef GNASH_DEBUG_AMF_DESERIALIZE
log_debug("amf0 ECMA_ARRAY prop name is
%s", name);
@@ -2381,7 +2374,8 @@
case amf::Element::DATE_AMF0:
{
if (b + 8 > end) {
- log_error(_("AMF0 read: premature end of input
reading Date type"));
+ log_error(_("AMF0 read: premature end of input
reading Date "
+ "type"));
return false;
}
double dub;
@@ -2396,10 +2390,12 @@
ret.set_as_object(obj);
if (b + 2 > end) {
- log_error(_("AMF0 read: premature end of input
reading timezone from Date type"));
+ log_error(_("AMF0 read: premature end of input
reading "
+ "timezone from Date type"));
return false;
}
- LOG_ONCE(log_unimpl("Timezone info from AMF0 encoded Date object
ignored"));
+ LOG_ONCE(log_unimpl("Timezone info from AMF0 encoded Date object "
+ "ignored"));
b+=2;
return true;
@@ -2418,7 +2414,8 @@
}
bool
-as_value::readAMF0(boost::uint8_t *&b, boost::uint8_t *end, int inType,
std::vector<as_object*>& objRefs, VM& vm)
+as_value::readAMF0(const boost::uint8_t *&b, const boost::uint8_t *end,
+ int inType, std::vector<as_object*>& objRefs, VM& vm)
{
return amf0_read_value(b, end, *this, inType, objRefs, vm);
}
@@ -2575,7 +2572,7 @@
log_debug(_("writeAMF0: serializing number '%g'"), d);
#endif
buf.appendByte(amf::Element::NUMBER_AMF0);
- amf::swapBytes(&d, 8); // this actually only swapps on
little-endian machines
+ amf::swapBytes(&d, 8); // this actually only swaps on
little-endian machines
buf.append(&d, 8);
return true;
}
=== modified file 'libcore/as_value.h'
--- a/libcore/as_value.h 2008-12-16 12:20:22 +0000
+++ b/libcore/as_value.h 2009-01-03 15:01:27 +0000
@@ -224,7 +224,8 @@
/// @param vm
/// Virtual machine to use for initialization of the values
(string_table)
///
- DSOEXPORT bool readAMF0(boost::uint8_t *&b, boost::uint8_t *end, int
inType,
+ DSOEXPORT bool readAMF0(const boost::uint8_t*& b,
+ const boost::uint8_t* const end, int inType,
std::vector<as_object*>& objRefs, VM& vm);
/// Serialize value in AMF0 format.
=== modified file 'libcore/asobj/Date_as.cpp'
--- a/libcore/asobj/Date_as.cpp 2008-12-31 12:53:47 +0000
+++ b/libcore/asobj/Date_as.cpp 2009-01-03 15:01:27 +0000
@@ -163,7 +163,7 @@
Date_as::Date_as(double value)
:
as_object(getDateInterface()),
- _value(value)
+ _timeValue(value)
{
}
@@ -179,7 +179,7 @@
"Thu", "Fri", "Sat" };
/// NaN and infinities all print as "Invalid Date"
- if (isNaN(_value) || isInf(_value)) {
+ if (isNaN(_timeValue) || isInf(_timeValue)) {
return "Invalid Date";
}
@@ -187,7 +187,7 @@
GnashTime gt;
// Time zone offset (including DST) as hours and minutes east of GMT
- localTime(_value, gt);
+ localTime(_timeValue, gt);
int offsetHours = gt.timeZoneOffset / 60;
int offsetMinutes = gt.timeZoneOffset % 60;
@@ -393,6 +393,7 @@
if ( !o )
{
o = new as_object(getObjectInterface());
+ VM::get().addStatic(o.get());
attachDateInterface(*o);
}
return o.get();
@@ -486,7 +487,8 @@
// due to shortcomings in the timezoneoffset calculation, but should
// be internally consistent.
double localTime = makeTimeValue(gt);
- date = new Date_as(localTime - clocktime::getTimeZoneOffset(localTime)
* 60000);
+ date = new Date_as(
+ localTime - clocktime::getTimeZoneOffset(localTime) * 60000);
}
return as_value(date.get());
=== modified file 'libcore/asobj/Date_as.h'
--- a/libcore/asobj/Date_as.h 2008-12-31 12:53:47 +0000
+++ b/libcore/asobj/Date_as.h 2009-01-03 15:01:27 +0000
@@ -30,9 +30,9 @@
explicit Date_as(double value = clocktime::getTicks());
- void setTimeValue(const double& value) { _value = value; }
+ void setTimeValue(const double& value) { _timeValue = value; }
- double getTimeValue() const { return _value; }
+ double getTimeValue() const { return _timeValue; }
static void registerNative(as_object& global);
@@ -44,7 +44,7 @@
private:
- double _value;
+ double _timeValue;
};
=== modified file 'libcore/asobj/NetConnection_as.cpp'
--- a/libcore/asobj/NetConnection_as.cpp 2008-12-20 16:06:27 +0000
+++ b/libcore/asobj/NetConnection_as.cpp 2009-01-03 15:01:27 +0000
@@ -394,8 +394,8 @@
#endif
boost::int16_t si;
boost::uint16_t li;
- boost::uint8_t *b = reply.data() + reply_start;
- boost::uint8_t *end = reply.data() + reply.size();
+ const boost::uint8_t *b = reply.data() + reply_start;
+ const boost::uint8_t *end = reply.data() + reply.size();
// parse header
b += 2; // skip version indicator and client id
@@ -477,13 +477,19 @@
int ns = 1; // next slash position
while (ns<si-1 && *(b+ns) != '/') ++ns;
if ( ns >= si-1 ) {
- std::string msg(reinterpret_cast<char*>(b),
si);
- log_error("NetConnection::call(): invalid
reply message name (%s)", msg);
+ std::string msg(
+ reinterpret_cast<const char*>(b), si);
+ log_error("NetConnection::call(): invalid "
+ "reply message name (%s)", msg);
break;
}
- std::string id(reinterpret_cast<char*>(b), ns);
- std::string
methodName(reinterpret_cast<char*>(b+ns+1), si-ns-1);
+ std::string id(reinterpret_cast<const char*>(b),
+ ns);
+
+ std::string methodName(
+ reinterpret_cast<const char*>(b+ns+1),
+ si-ns-1);
b += si;
=== modified file 'libcore/asobj/NetStream_as.cpp'
--- a/libcore/asobj/NetStream_as.cpp 2008-12-15 08:08:03 +0000
+++ b/libcore/asobj/NetStream_as.cpp 2009-01-03 16:34:08 +0000
@@ -45,7 +45,15 @@
#include "StreamProvider.h"
#include "sound_handler.h"
-#include <boost/algorithm/string/case_conv.hpp> // for PROPNAME
+// For ntohs in amf conversion. FIXME: do this somewhere
+// more appropriate. There's AMF code scattered all over the place.
+#if !defined(HAVE_WINSOCK_H) || defined(__OS2__)
+# include <sys/types.h>
+# include <arpa/inet.h>
+#else
+# include <windows.h>
+# include <io.h>
+#endif
// Define the following macro to have status notification handling debugged
//#define GNASH_DEBUG_STATUS
@@ -74,6 +82,9 @@
as_object* getNetStreamInterface();
void attachNetStreamInterface(as_object& o);
+
+ // TODO: see where this can be done more centrally.
+ void executeTag(const SimpleBuffer& _buffer, as_object* thisPtr, VM& vm);
}
/// Contruct a NetStream object.
@@ -333,7 +344,9 @@
as_value
NetStream_as::advanceWrapper(const fn_call& fn)
{
- boost::intrusive_ptr<NetStream_as> ptr =
ensureType<NetStream_as>(fn.this_ptr);
+ boost::intrusive_ptr<NetStream_as> ptr =
+ ensureType<NetStream_as>(fn.this_ptr);
+
ptr->advance();
return as_value();
}
@@ -531,7 +544,7 @@
inputPos = 0;
- if ( ! _mediaHandler )
+ if (!_mediaHandler)
{
LOG_ONCE( log_error(_("No Media handler registered, can't "
"parse NetStream input")) );
@@ -1256,6 +1269,7 @@
return _videoDecoder->width();
}
+
void
NetStream_as::advance()
{
@@ -1284,7 +1298,7 @@
// Check decoding status
if ( decodingStatus() == DEC_DECODING && bufferLen == 0 )
{
- if ( ! parsingComplete )
+ if (!parsingComplete)
{
#ifdef GNASH_DEBUG_DECODING
log_debug("%p.advance: buffer empty while decoding,"
@@ -1321,7 +1335,8 @@
// The very first video frame we want to provide
// as soon as possible (if not paused),
// reguardless bufferLength...
- if ( ! m_imageframe.get() && _playHead.getState() !=
PlayHead::PLAY_PAUSED )
+ if (!m_imageframe.get() &&
+ _playHead.getState() != PlayHead::PLAY_PAUSED)
{
log_debug("refreshing video frame for the first time");
refreshVideoFrame(true);
@@ -1331,9 +1346,9 @@
}
#ifdef GNASH_DEBUG_DECODING
- log_debug("%p.advance: buffer full (or parsing completed), resuming
playback clock"
- " - position=%d, buffer=%d/%d",
- this, _playHead.getPosition(), bufferLen, m_bufferTime);
+ log_debug("%p.advance: buffer full (or parsing completed), "
+ "resuming playback clock - position=%d, buffer=%d/%d",
+ this, _playHead.getPosition(), bufferLen, m_bufferTime);
#endif // GNASH_DEBUG_DECODING
setStatus(bufferFull);
@@ -1349,12 +1364,20 @@
// up to current playhead
refreshAudioBuffer();
- // Advance PlayeHead position if current one was consumed
+ // Advance PlayHead position if current one was consumed
// by all available consumers
_playHead.advanceIfConsumed();
- // Process media tags
- m_parser->processTags(_playHead.getPosition(), this, getVM());
+ media::MediaParser::OrderedMetaTags tags;
+
+ m_parser->fetchMetaTags(tags, _playHead.getPosition());
+
+ if (tags.empty()) return;
+
+ for (media::MediaParser::OrderedMetaTags::iterator i = tags.begin(),
+ e = tags.end(); i != e; ++i) {
+ executeTag(**i, this, getVM());
+ }
}
boost::int32_t
@@ -1363,11 +1386,13 @@
return _playHead.getPosition();
}
-void NetStream_as::pausePlayback()
+void
+NetStream_as::pausePlayback()
{
GNASH_REPORT_FUNCTION;
- PlayHead::PlaybackStatus oldStatus =
_playHead.setState(PlayHead::PLAY_PAUSED);
+ PlayHead::PlaybackStatus oldStatus =
+ _playHead.setState(PlayHead::PLAY_PAUSED);
// Disconnect the soundhandler if we were playing before
if ( oldStatus == PlayHead::PLAY_PLAYING )
@@ -1376,11 +1401,13 @@
}
}
-void NetStream_as::unpausePlayback()
+void
+NetStream_as::unpausePlayback()
{
GNASH_REPORT_FUNCTION;
- PlayHead::PlaybackStatus oldStatus =
_playHead.setState(PlayHead::PLAY_PLAYING);
+ PlayHead::PlaybackStatus oldStatus =
+ _playHead.setState(PlayHead::PLAY_PLAYING);
// Re-connect to the soundhandler if we were paused before
if ( oldStatus == PlayHead::PLAY_PAUSED )
@@ -1441,10 +1468,12 @@
}
try {
- _auxStreamer =
_soundHandler->attach_aux_streamer(BufferedAudioStreamer::fetchWrapper,
- (void*)this);
- } catch (SoundException& e) {
- log_error("Could not attach NetStream aux streamer to sound handler:
%s", e.what());
+ _auxStreamer = _soundHandler->attach_aux_streamer(
+ BufferedAudioStreamer::fetchWrapper, (void*)this);
+ }
+ catch (SoundException& e) {
+ log_error("Could not attach NetStream aux streamer to sound handler: "
+ "%s", e.what());
}
}
@@ -1463,9 +1492,12 @@
// audio callback, possibly running in a separate thread
unsigned int
-BufferedAudioStreamer::fetchWrapper(void *owner, boost::int16_t* samples,
unsigned int nSamples, bool& eof)
+BufferedAudioStreamer::fetchWrapper(void *owner, boost::int16_t* samples,
+ unsigned int nSamples, bool& eof)
{
- BufferedAudioStreamer* streamer =
static_cast<BufferedAudioStreamer*>(owner);
+ BufferedAudioStreamer* streamer =
+ static_cast<BufferedAudioStreamer*>(owner);
+
return streamer->fetch(samples, nSamples, eof);
}
@@ -1903,5 +1935,43 @@
return o.get();
}
+void
+executeTag(const SimpleBuffer& _buffer, as_object* thisPtr, VM& vm)
+{
+ const boost::uint8_t* ptr = _buffer.data();
+ const boost::uint8_t* endptr = ptr + _buffer.size();
+
+ if ( ptr + 2 > endptr ) {
+ log_error("Premature end of AMF in NetStream metatag");
+ return;
+ }
+ boost::uint16_t length = ntohs((*(boost::uint16_t *)ptr) & 0xffff);
+ ptr += 2;
+
+ if ( ptr + length > endptr ) {
+ log_error("Premature end of AMF in NetStream metatag");
+ return;
+ }
+
+ std::string funcName(reinterpret_cast<const char*>(ptr), length);
+ ptr += length;
+
+ log_debug("funcName: %s", funcName);
+
+ string_table& st = vm.getStringTable();
+ string_table::key funcKey = st.find(funcName);
+
+ as_value arg;
+ std::vector<as_object*> objRefs;
+ if ( ! arg.readAMF0(ptr, endptr, -1, objRefs, vm) )
+ {
+ log_error("Could not convert FLV metatag to as_value, but will
try "
+ "passing it anyway. It's an %s", arg);
+ }
+
+ log_debug("Calling %s(%s)", funcName, arg);
+ thisPtr->callMethod(funcKey, arg);
+}
+
} // anonymous namespace
} // gnash namespace
=== modified file 'libcore/asobj/SharedObject_as.cpp'
--- a/libcore/asobj/SharedObject_as.cpp 2009-01-02 12:00:13 +0000
+++ b/libcore/asobj/SharedObject_as.cpp 2009-01-03 15:01:27 +0000
@@ -953,20 +953,20 @@
}
boost::scoped_array<boost::uint8_t> sbuf(new boost::uint8_t[st.st_size]);
- boost::uint8_t *buf = sbuf.get();
- boost::uint8_t *end = buf + st.st_size;
+ const boost::uint8_t *buf = sbuf.get();
+ const boost::uint8_t *end = buf + st.st_size;
try
{
std::ifstream ifs(filespec.c_str(), std::ios::binary);
- ifs.read(reinterpret_cast<char *>(buf), st.st_size);
+ ifs.read(reinterpret_cast<char*>(sbuf.get()), st.st_size);
// TODO check initial bytes, and print warnings if they are fishy
buf += 16; // skip const-length headers
// skip past name TODO add sanity check
- buf += ntohs(*(reinterpret_cast<boost::uint16_t*>(buf)));
+ buf += ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
buf += 2;
buf += 4; // skip past padding
@@ -986,7 +986,7 @@
"byte %s", buf - sbuf.get());
// read property name
boost::uint16_t len =
- ntohs(*(reinterpret_cast<boost::uint16_t*>(buf)));
+ ntohs(*(reinterpret_cast<const boost::uint16_t*>(buf)));
buf += 2;
if( buf + len >= end )
@@ -998,7 +998,7 @@
log_error("SharedObject::readSOL: empty property name");
break;
}
- std::string prop_name(reinterpret_cast<char*>(buf), len);
+ std::string prop_name(reinterpret_cast<const char*>(buf), len);
buf += len;
// read value
=== modified file 'libcore/parser/action_buffer.h'
--- a/libcore/parser/action_buffer.h 2008-11-19 16:51:17 +0000
+++ b/libcore/parser/action_buffer.h 2009-01-02 16:08:00 +0000
@@ -64,11 +64,6 @@
///
void read(SWFStream& in, unsigned long endPos);
- bool is_null() const
- {
- return (m_buffer.size() < 1 || m_buffer[0] == 0);
- }
-
size_t size() const { return m_buffer.size(); }
boost::uint8_t operator[] (size_t off) const
@@ -98,52 +93,6 @@
return reinterpret_cast<const char*>(&m_buffer[pc]);
}
- /// Get a variable length 32-bit integer from the stream.
- /// Store its length in the passed boost::uint8_t.
- boost::uint32_t read_V32(size_t pc, boost::uint8_t& length) const
- {
- const size_t buflen = m_buffer.size();
- const std::string err = _("Attempt to read outside action buffer");
-
- if (pc >= buflen) throw ActionParserException(err);
-
- boost::uint32_t res = m_buffer[pc];
- if (!(res & 0x00000080))
- {
- length = 1;
- return res;
- }
-
- if (pc + 1 >= buflen) throw ActionParserException(err);
- res = (res & 0x0000007F) | (m_buffer[pc + 1] << 7);
- if (!(res & 0x00004000))
- {
- length = 2;
- return res;
- }
-
- if (pc + 2 >= buflen) throw ActionParserException(err);
- res = (res & 0x00003FFF) | (m_buffer[pc + 2] << 14);
- if (!(res & 0x00200000))
- {
- length = 3;
- return res;
- }
-
- if (pc + 3 >= buflen) throw ActionParserException(err);
- res = (res & 0x001FFFFF) | (m_buffer[pc + 3] << 21);
- if (!(res & 0x10000000))
- {
- length = 4;
- return res;
- }
-
- if (pc + 4 >= buflen) throw ActionParserException(err);
- res = (res & 0x0FFFFFFF) | (m_buffer[pc + 4] << 28);
- length = 5;
- return res;
- }
-
/// Get a pointer to the current instruction within the code
const unsigned char* getFramePointer(size_t pc) const
{
=== modified file 'libmedia/AudioDecoderNellymoser.cpp'
--- a/libmedia/AudioDecoderNellymoser.cpp 2008-10-29 22:32:10 +0000
+++ b/libmedia/AudioDecoderNellymoser.cpp 2009-01-03 15:01:27 +0000
@@ -50,10 +50,9 @@
#include "SoundInfo.h"
#include "log.h"
-#include "VM.h" // for randonNumberGenerator
-
#include <ctime>
#include <cmath>
+#include <boost/random.hpp>
namespace gnash {
namespace media {
@@ -648,10 +647,13 @@
gimme_random()
{
using namespace boost;
- VM::RNG& rnd = VM::get().randomNumberGenerator();
+
+ typedef boost::mt11213b RNG;
+
+ static RNG rnd;
uniform_int<> dist(0, std::numeric_limits<int>::max());
- variate_generator<VM::RNG&, uniform_int<> > uni(rnd, dist);
+ variate_generator<RNG, uniform_int<> > uni(rnd, dist);
return uni();
}
=== modified file 'libmedia/FLVParser.cpp'
--- a/libmedia/FLVParser.cpp 2008-12-27 19:02:45 +0000
+++ b/libmedia/FLVParser.cpp 2009-01-03 15:01:27 +0000
@@ -28,19 +28,10 @@
#include "IOChannel.h"
#include "SimpleBuffer.h"
-#include "as_object.h"
#include "element.h"
-#include "VM.h"
#include <string>
#include <iosfwd>
-#if !defined(HAVE_WINSOCK_H) || defined(__OS2__)
-# include <sys/types.h>
-# include <arpa/inet.h>
-#else
-# include <windows.h>
-# include <io.h>
-#endif
#define PADDING_BYTES 64
@@ -67,6 +58,21 @@
namespace gnash {
namespace media {
+namespace {
+
+/// Functor for use when transforming a map into a vector of mapped values.
+template<typename T>
+struct SecondElement
+{
+ typedef typename T::second_type result_type;
+
+ const result_type& operator()(const T& pair) const
+ {
+ return pair.second;
+ }
+};
+
+}
const boost::uint16_t FLVParser::FLVAudioTag::flv_audio_rates [] = {5500,
11000, 22050, 44100};
@@ -82,19 +88,16 @@
_cuePoints(),
_indexingCompleted(false)
{
- if ( ! parseHeader() )
- throw GnashException("FLVParser couldn't parse header from
input");
+ if (!parseHeader()) {
+ throw MediaException("FLVParser couldn't parse header from
input");
+ }
+
startParserThread();
}
FLVParser::~FLVParser()
{
stopParserThread();
-
- for (MetaTags::iterator i=_metaTags.begin(), e=_metaTags.end(); i!=e;
++i)
- {
- delete *i;
- }
}
@@ -102,7 +105,6 @@
bool
FLVParser::seek(boost::uint32_t& time)
{
- //GNASH_REPORT_FUNCTION;
boost::mutex::scoped_lock streamLock(_streamMutex);
// we might obtain this lock while the parser is pushing the last
@@ -115,8 +117,6 @@
// while the parser was pushing to queue
_seekRequest = true;
-
-
if ( _cuePoints.empty() )
{
log_debug("No known cue points yet, can't seek");
@@ -131,7 +131,8 @@
}
long lowerBoundPosition = it->second;
- log_debug("Seek requested to time %d triggered seek to cue point at
position %d and time %d", time, it->second, it->first);
+ log_debug("Seek requested to time %d triggered seek to cue point at "
+ "position %d and time %d", time, it->second, it->first);
time = it->first;
_lastParsedPosition=lowerBoundPosition;
_parsingComplete=false; // or NetStream will send the Play.Stop event...
@@ -201,7 +202,9 @@
std::auto_ptr<EncodedAudioFrame> frame;
if ( ! _audio ) {
- log_error(_("Unexpected audio tag found at offset %d FLV stream
advertising no audio in header. We'll warn only once for each FLV, expecting
any further audio tag."), thisTagPos);
+ log_error(_("Unexpected audio tag found at offset %d FLV stream
"
+ "advertising no audio in header. We'll warn only once for "
+ "each FLV, expecting any further audio tag."), thisTagPos);
_audio = true; // TOCHECK: is this safe ?
}
@@ -223,7 +226,8 @@
// audio format has been noted, so we do that now
if ( !_audioInfo.get() )
{
- _audioInfo.reset( new AudioInfo(audiotag.codec,
audiotag.samplerate, audiotag.samplesize, audiotag.stereo, 0, FLASH) );
+ _audioInfo.reset(new AudioInfo(audiotag.codec,
audiotag.samplerate,
+ audiotag.samplesize, audiotag.stereo, 0, FLASH) );
if (header) {
boost::uint8_t* newbuf = new
boost::uint8_t[frame->dataSize];
memcpy(newbuf, frame->data.get(), frame->dataSize);
@@ -245,7 +249,9 @@
FLVParser::parseVideoTag(const FLVTag& flvtag, const FLVVideoTag& videotag,
boost::uint32_t thisTagPos)
{
if ( ! _video ) {
- log_error(_("Unexpected video tag found at offset %d of FLV
stream advertising no video in header. We'll warn only once per FLV, expecting
any further video tag."), thisTagPos);
+ log_error(_("Unexpected video tag found at offset %d of FLV
stream "
+ "advertising no video in header. We'll warn only once per "
+ "FLV, expecting any further video tag."), thisTagPos);
_video = true; // TOCHECK: is this safe ?
}
@@ -306,14 +312,10 @@
}
-
-
-
// would be called by parser thread
-bool FLVParser::parseNextTag(bool index_only)
+bool
+FLVParser::parseNextTag(bool index_only)
{
- //GNASH_REPORT_FUNCTION;
-
// lock the stream while reading from it, so actionscript
// won't mess with the parser on seek or on getBytesLoaded
boost::mutex::scoped_lock streamLock(_streamMutex);
@@ -351,20 +353,22 @@
if ( actuallyRead < 12 )
{
if ( actuallyRead )
- log_error("FLVParser::parseNextTag: can't read tag info
(needed 12 bytes, only got %d)", actuallyRead);
+ log_error("FLVParser::parseNextTag: can't read tag info
"
+ "(needed 12 bytes, only got %d)", actuallyRead);
// else { assert(_stream->eof(); } ?
completed = true;
- // update bytes loaded
- boost::mutex::scoped_lock lock(_bytesLoadedMutex);
+ // update bytes loaded
+ boost::mutex::scoped_lock lock(_bytesLoadedMutex);
_bytesLoaded = _stream->tell();
return false;
}
FLVTag flvtag(chunk);
- position += 15 + flvtag.body_size; // may be _lastParsedPosition OR
_nextPosToIndex
+ // May be _lastParsedPosition OR _nextPosToIndex
+ position += 15 + flvtag.body_size;
bool doIndex = (_lastParsedPosition+4 > _nextPosToIndex) || index_only;
if ( _lastParsedPosition > _nextPosToIndex )
@@ -463,19 +467,21 @@
}
boost::mutex::scoped_lock lock(_metaTagsMutex);
- _metaTags.push_back(new MetaTag(flvtag.timestamp, metaTag));
+ _metaTags.insert(std::make_pair(flvtag.timestamp,
metaTag.release()));
}
else
{
- log_error(_("FLVParser::parseNextTag: unknown FLV tag type
%d"), (int)chunk[0]);
+ log_error(_("FLVParser::parseNextTag: unknown FLV tag type %d"),
+ (int)chunk[0]);
return false;
}
_stream->read(chunk, 4);
- boost::uint32_t prevtagsize = chunk[0] << 24 | chunk[1] << 16 |
chunk[2] << 8 | chunk[3];
+ boost::uint32_t prevtagsize = chunk[0] << 24 | chunk[1] << 16 |
+ chunk[2] << 8 | chunk[3];
if (prevtagsize != flvtag.body_size + 11) {
- log_error(_("Corrupt FLV: previous tag size record (%1%)
unexpected (actual size: %2%)"),
- prevtagsize, flvtag.body_size + 11);
+ log_error(_("Corrupt FLV: previous tag size record (%1%)
unexpected "
+ "(actual size: %2%)"), prevtagsize, flvtag.body_size + 11);
}
return true;
@@ -497,7 +503,7 @@
_lastParsedPosition = _bytesLoaded = _nextPosToIndex = 9;
- if (!std::equal(header, header+3, "FLV")) {
+ if (!std::equal(header, header + 3, "FLV")) {
return false;
}
@@ -513,7 +519,8 @@
return true;
}
-inline boost::uint32_t FLVParser::getUInt24(boost::uint8_t* in)
+inline boost::uint32_t
+FLVParser::getUInt24(boost::uint8_t* in)
{
// The bits are in big endian order
return (in[0] << 16) | (in[1] << 8) | in[2];
@@ -537,18 +544,21 @@
frame->dataSize = dataSize;
frame->timestamp = timestamp;
- unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS,
dataSize+PADDING_BYTES);
-
- frame->data.reset( new boost::uint8_t[chunkSize] );
- size_t bytesread = _stream->read(frame->data.get(), dataSize);
+ const size_t chunkSize = smallestMultipleContaining(READ_CHUNKS,
+ dataSize + PADDING_BYTES);
+
+ frame->data.reset(new boost::uint8_t[chunkSize]);
+
+ const size_t bytesread = _stream->read(frame->data.get(), dataSize);
if ( bytesread < dataSize )
{
- log_error("FLVParser::readAudioFrame: could only read %d/%d
bytes", bytesread, dataSize);
+ log_error("FLVParser::readAudioFrame: could only read %d/%d
bytes",
+ bytesread, dataSize);
}
- unsigned long int padding = chunkSize-dataSize;
+ const size_t padding = chunkSize - dataSize;
assert(padding);
- memset(frame->data.get() + bytesread, 0, padding);
+ std::fill_n(frame->data.get() + bytesread, padding, 0);
return frame;
}
@@ -560,76 +570,37 @@
{
std::auto_ptr<EncodedVideoFrame> frame;
- unsigned long int chunkSize = smallestMultipleContaining(READ_CHUNKS,
dataSize+PADDING_BYTES);
+ const size_t chunkSize = smallestMultipleContaining(READ_CHUNKS,
+ dataSize + PADDING_BYTES);
boost::uint8_t* data = new boost::uint8_t[chunkSize];
size_t bytesread = _stream->read(data, dataSize);
- unsigned long int padding = chunkSize-dataSize;
+ const size_t padding = chunkSize - dataSize;
assert(padding);
- memset(data + bytesread, 0, padding);
+ std::fill_n(data + bytesread, padding, 0);
// We won't need frameNum, so will set to zero...
// TODO: fix this ?
// NOTE: ownership of 'data' is transferred here
- frame.reset( new EncodedVideoFrame(data, dataSize, 0, timestamp) );
+ frame.reset(new EncodedVideoFrame(data, dataSize, 0, timestamp));
return frame;
}
+
void
-FLVParser::processTags(boost::uint64_t ts, as_object* thisPtr, VM& vm)
+FLVParser::fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts)
{
boost::mutex::scoped_lock lock(_metaTagsMutex);
- while (!_metaTags.empty())
- {
- if ( _metaTags.front()->timestamp() > ts ) break;
-
- std::auto_ptr<MetaTag> tag ( _metaTags.front() );
- _metaTags.pop_front();
- tag->execute(thisPtr, vm);
-
- }
-}
-
-void
-FLVParser::MetaTag::execute(as_object* thisPtr, VM& vm)
-{
- boost::uint8_t* ptr = _buffer->data();
- boost::uint8_t* endptr = ptr+_buffer->size();
-
- //log_debug("FLV meta: %s", hexify(ptr, 32, 0));
- //log_debug("FLV meta: %s", hexify(ptr, 32, 1));
-
- if ( ptr + 2 > endptr ) {
- log_error("Premature end of AMF in FLV metatag");
- return;
- }
- boost::uint16_t length = ntohs((*(boost::uint16_t *)ptr) & 0xffff);
- ptr+=2;
-
- if ( ptr + length > endptr ) {
- log_error("Premature end of AMF in FLV metatag");
- return;
- }
- std::string funcName((char*)ptr, length); // TODO: check for OOB !
- ptr += length;
-
- log_debug("funcName: %s", funcName);
-
- string_table& st = vm.getStringTable();
- string_table::key funcKey = st.find(funcName);
-
- as_value arg;
- std::vector<as_object*> objRefs;
- if ( ! arg.readAMF0(ptr, endptr, -1, objRefs, vm) )
- {
- log_error("Could not convert FLV metatag to as_value, but will
try passing it anyway. It's an %s", arg);
- //return;
- }
-
- log_debug("Calling %s(%s)", funcName, arg);
- thisPtr->callMethod(funcKey, arg);
+ if (!_metaTags.empty())
+ {
+ MetaTags::iterator it = _metaTags.upper_bound(ts);
+ std::transform(_metaTags.begin(), it, std::back_inserter(tags),
+ SecondElement<MetaTags::value_type>());
+ _metaTags.erase(_metaTags.begin(), it);
+
+ }
}
} // end of gnash::media namespace
=== modified file 'libmedia/FLVParser.h'
--- a/libmedia/FLVParser.h 2008-10-27 12:03:47 +0000
+++ b/libmedia/FLVParser.h 2009-01-03 15:29:43 +0000
@@ -20,29 +20,23 @@
// Information about the FLV format can be found at http://osflash.org/flv
-#ifndef __FLVPARSER_H__
-#define __FLVPARSER_H__
+#ifndef GNASH_FLVPARSER_H
+#define GNASH_FLVPARSER_H
#include "dsodefs.h"
#include "MediaParser.h" // for inheritance
-#include "SimpleBuffer.h" // for MetaTag destructor
+#include "SimpleBuffer.h"
+#include <set>
#include <vector>
#include <memory>
#include <map>
#include <boost/thread/mutex.hpp>
-// Forward declarations
-namespace gnash {
- class as_object;
- class VM;
-}
-
namespace gnash {
namespace media {
-
/// Extra video info found in some FLV embedded streams
//
/// This is basically composed by an header for the audio stream
@@ -94,11 +88,11 @@
/// @todo take a SimpleBuffer by auto_ptr
///
ExtraAudioInfoFlv(boost::uint8_t* extradata, size_t datasize)
- :
- data(extradata),
- size(datasize)
- {
- }
+ :
+ data(extradata),
+ size(datasize)
+ {
+ }
/// Audio stream header
boost::scoped_array<boost::uint8_t> data;
@@ -111,6 +105,50 @@
class DSOEXPORT FLVParser : public MediaParser
{
+public:
+
+ /// \brief
+ /// Create an FLV parser reading input from
+ /// the given IOChannel
+ //
+ /// @param lt
+ /// IOChannel to use for input.
+ /// Ownership transferred.
+ ///
+ FLVParser(std::auto_ptr<IOChannel> lt);
+
+ /// Kills the parser...
+ ~FLVParser();
+
+ // see dox in MediaParser.h
+ virtual bool seek(boost::uint32_t&);
+
+ // see dox in MediaParser.h
+ virtual bool parseNextChunk();
+
+ // see dox in MediaParser.h
+ boost::uint64_t getBytesLoaded() const;
+
+ // see dox in MediaParser.h
+ bool indexingCompleted() const
+ {
+ return _indexingCompleted;
+ }
+
+ /// Retrieve any parsed metadata tags up to a specified timestamp.
+ //
+ /// This copies pointers to a SimpleBuffer of AMF data from _metaTags,
+ /// then removes those pointers from the MetaTags map. Any metadata later
+ /// than the timestamp is kept until fetchMetaTags is called again (or
+ /// the dtor is called).
+ //
+ /// @param ts The latest timestamp to retrieve metadata for.
+ /// @param tags This is filled with shared pointers to metatags in
+ /// timestamp order. Ownership of the data is shared. It
+ /// is destroyed automatically along with the last owner.
+ //
+ virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
+
private:
enum tagType
@@ -123,9 +161,10 @@
struct FLVTag : public boost::noncopyable
{
FLVTag(boost::uint8_t* stream)
- : type(stream[0]),
- body_size(getUInt24(stream+1)),
- timestamp(getUInt24(stream+4) | (stream[7] << 24) )
+ :
+ type(stream[0]),
+ body_size(getUInt24(stream+1)),
+ timestamp(getUInt24(stream+4) | (stream[7] << 24) )
{}
/// Equals tagType
@@ -137,10 +176,11 @@
struct FLVAudioTag : public boost::noncopyable
{
FLVAudioTag(const boost::uint8_t& byte)
- : codec( (byte & 0xf0) >> 4 ),
- samplerate( flv_audio_rates[(byte & 0x0C) >> 2] ),
- samplesize( 1 + ((byte & 0x02) >> 1)),
- stereo( (byte & 0x01) )
+ :
+ codec( (byte & 0xf0) >> 4 ),
+ samplerate( flv_audio_rates[(byte & 0x0C) >> 2] ),
+ samplesize( 1 + ((byte & 0x02) >> 1)),
+ stereo( (byte & 0x01) )
{
}
@@ -153,9 +193,12 @@
boost::uint8_t samplesize;
bool stereo;
- private:
- static const boost::uint16_t flv_audio_rates[];
- };
+
+ private:
+
+ static const boost::uint16_t flv_audio_rates[];
+
+ };
enum frameType
{
@@ -167,8 +210,9 @@
struct FLVVideoTag : public boost::noncopyable
{
FLVVideoTag(const boost::uint8_t& byte)
- : frametype( (byte & 0xf0) >> 4 ),
- codec( byte & 0x0f )
+ :
+ frametype( (byte & 0xf0) >> 4 ),
+ codec( byte & 0x0f )
{}
/// Equals frameType
@@ -177,40 +221,6 @@
boost::uint8_t codec;
};
-public:
-
- /// \brief
- /// Create an FLV parser reading input from
- /// the given IOChannel
- //
- /// @param lt
- /// IOChannel to use for input.
- /// Ownership transferred.
- ///
- FLVParser(std::auto_ptr<IOChannel> lt);
-
- /// Kills the parser...
- ~FLVParser();
-
- // see dox in MediaParser.h
- virtual bool seek(boost::uint32_t&);
-
- // see dox in MediaParser.h
- virtual bool parseNextChunk();
-
- // see dox in MediaParser.h
- boost::uint64_t getBytesLoaded() const;
-
- // see dox in MediaParser.h
- bool indexingCompleted() const
- {
- return _indexingCompleted;
- }
-
- virtual void processTags(boost::uint64_t ts, as_object* thisPtr, VM&
env);
-
-private:
-
/// Parses next tag from the file
//
/// Returns true if something was parsed, false otherwise.
@@ -218,11 +228,16 @@
///
bool parseNextTag(bool index_only);
- std::auto_ptr<EncodedAudioFrame> parseAudioTag(const FLVTag& flvtag,
const FLVAudioTag& audiotag, boost::uint32_t thisTagPos);
- std::auto_ptr<EncodedVideoFrame> parseVideoTag(const FLVTag& flvtag,
const FLVVideoTag& videotag, boost::uint32_t thisTagPos);
+ std::auto_ptr<EncodedAudioFrame> parseAudioTag(const FLVTag& flvtag,
+ const FLVAudioTag& audiotag, boost::uint32_t thisTagPos);
+
+ std::auto_ptr<EncodedVideoFrame> parseVideoTag(const FLVTag& flvtag,
+ const FLVVideoTag& videotag, boost::uint32_t thisTagPos);
void indexAudioTag(const FLVTag& tag, boost::uint32_t thisTagPos);
- void indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag,
boost::uint32_t thisTagPos);
+
+ void indexVideoTag(const FLVTag& tag, const FLVVideoTag& videotag,
+ boost::uint32_t thisTagPos);
/// Parses the header of the file
bool parseHeader();
@@ -259,9 +274,11 @@
/// Audio stream is present
bool _video;
- std::auto_ptr<EncodedAudioFrame> readAudioFrame(boost::uint32_t
dataSize, boost::uint32_t timestamp);
+ std::auto_ptr<EncodedAudioFrame>
+ readAudioFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
- std::auto_ptr<EncodedVideoFrame> readVideoFrame(boost::uint32_t
dataSize, boost::uint32_t timestamp);
+ std::auto_ptr<EncodedVideoFrame>
+ readVideoFrame(boost::uint32_t dataSize, boost::uint32_t timestamp);
/// Position in input stream for each cue point
/// first: timestamp
@@ -271,27 +288,12 @@
bool _indexingCompleted;
- class MetaTag {
- public:
- MetaTag(boost::uint64_t t, std::auto_ptr<SimpleBuffer> b)
- :
- _timestamp(t),
- _buffer(b)
- {}
-
- void execute(as_object* thisPtr, VM& env);
- boost::uint64_t timestamp() const { return _timestamp; }
- private:
- boost::uint64_t _timestamp;
- std::auto_ptr<SimpleBuffer> _buffer;
- };
-
- typedef std::deque<MetaTag*> MetaTags;
- MetaTags _metaTags;
- boost::mutex _metaTagsMutex;
+ MetaTags _metaTags;
+
+ boost::mutex _metaTagsMutex;
};
} // end of gnash::media namespace
} // end of gnash namespace
-#endif // __FLVPARSER_H__
+#endif
=== modified file 'libmedia/Makefile.am'
--- a/libmedia/Makefile.am 2008-11-12 15:29:13 +0000
+++ b/libmedia/Makefile.am 2009-01-03 15:01:27 +0000
@@ -32,11 +32,8 @@
libgnashmedia_la_CPPFLAGS = \
-I$(top_srcdir)/libamf \
-I$(top_srcdir)/libnet \
- -I$(top_srcdir)/backend \
-I$(top_srcdir)/libbase \
-I$(top_srcdir)/libcore \
- -I$(top_srcdir)/libcore/vm \
- -I$(top_srcdir)/libcore/parser \
$(PTHREAD_CFLAGS) \
$(DMALLOC_CFLAGS) \
$(OPENGL_CFLAGS) \
@@ -170,8 +167,7 @@
if WIN32
libgnashmedia_la_LDFLAGS += -no-undefined
libgnashmedia_la_LIBADD += \
- $(top_builddir)/libbase/libgnashbase.la \
- $(top_builddir)/libcore/libgnashcore.la \
+ $(top_builddir)/libbase/libgnashbase.la
-lintl
endif
=== modified file 'libmedia/MediaHandler.cpp'
--- a/libmedia/MediaHandler.cpp 2008-11-27 13:05:09 +0000
+++ b/libmedia/MediaHandler.cpp 2009-01-03 09:54:35 +0000
@@ -38,9 +38,8 @@
std::auto_ptr<MediaHandler> MediaHandler::_handler;
-/* public static */
bool
-MediaHandler::isFLV(IOChannel& stream)
+MediaHandler::isFLV(IOChannel& stream) throw (IOException)
{
char head[4] = {0, 0, 0, 0};
stream.seek(0);
@@ -49,11 +48,11 @@
if (actuallyRead < 3)
{
- log_error(_("MediaHandler::isFLV: Could not read 3 bytes from
input stream"));
- return false;
+ throw IOException(_("MediaHandler::isFLV: Could not read 3
bytes "
+ "from input stream"));
}
- if (std::string(head) != "FLV") return false;
+ if (!std::equal(head, head + 3, "FLV")) return false;
return true;
}
@@ -62,12 +61,18 @@
{
std::auto_ptr<MediaParser> parser;
- if ( ! isFLV(*stream) )
- {
- log_error(_("MediaHandler::createMediaParser: only FLV input is
"
- "supported by this MediaHandler"));
- return parser;
- }
+ try {
+ if (!isFLV(*stream))
+ {
+ log_error(_("MediaHandler::createMediaParser: only FLV input is "
+ "supported by this MediaHandler"));
+ return parser;
+ }
+ }
+ catch (IOException& m) {
+ log_error(_("Exception while reading from stream: %s"), m.what());
+ return parser;
+ }
parser.reset( new FLVParser(stream) );
assert(! stream.get() ); // TODO: when ownership will be transferred...
=== modified file 'libmedia/MediaHandler.h'
--- a/libmedia/MediaHandler.h 2008-10-28 19:26:42 +0000
+++ b/libmedia/MediaHandler.h 2009-01-03 09:54:35 +0000
@@ -130,7 +130,9 @@
std::auto_ptr<AudioDecoder> createFlashAudioDecoder(const AudioInfo& info);
/// Return true if input stream is an FLV
- bool isFLV(IOChannel& stream);
+ //
+ /// If this cannot read the necessary 3 bytes, it throws an IOException.
+ bool isFLV(IOChannel& stream) throw (IOException);
MediaHandler() {}
=== modified file 'libmedia/MediaParser.cpp'
--- a/libmedia/MediaParser.cpp 2008-10-22 21:11:11 +0000
+++ b/libmedia/MediaParser.cpp 2009-01-03 15:01:27 +0000
@@ -20,9 +20,9 @@
#include "MediaParser.h"
#include "log.h"
+#include "GnashSleep.h" // for usleep.
#include <boost/bind.hpp>
-#include "GnashSleep.h" // for usleep.
// Define this to get debugging output from MediaParser
//#define GNASH_DEBUG_MEDIAPARSER
@@ -380,11 +380,13 @@
void
-MediaParser::processTags(boost::uint64_t /*ts*/, as_object* /*thisPtr*/, VM&
/*env*/)
+MediaParser::fetchMetaTags(OrderedMetaTags& /*tags*/, boost::uint64_t /*ts*/)
{
}
-std::ostream& operator << (std::ostream& os, const VideoInfo& vi)
+
+std::ostream&
+operator<< (std::ostream& os, const VideoInfo& vi)
{
os << "codec:" << vi.codec << " (type " << vi.type << ") - "
<< "size:" << vi.width << "x" << vi.height << " - "
=== modified file 'libmedia/MediaParser.h'
--- a/libmedia/MediaParser.h 2008-12-03 23:36:26 +0000
+++ b/libmedia/MediaParser.h 2009-01-03 16:34:08 +0000
@@ -26,6 +26,7 @@
#include "IOChannel.h" // for inlines
#include "dsodefs.h" // DSOEXPORT
+#include "SimpleBuffer.h"
#include <boost/scoped_array.hpp>
#include <boost/thread/thread.hpp>
@@ -38,15 +39,10 @@
#define LOAD_MEDIA_IN_A_SEPARATE_THREAD 1
-// Forward declarations
-namespace gnash {
- class as_object;
- class VM;
-}
-
namespace gnash {
namespace media {
+
/// Video frame types
enum videoFrameType
{
@@ -435,7 +431,14 @@
{
public:
- MediaParser(std::auto_ptr<IOChannel> stream);
+ /// A container for executable MetaTags contained in media streams.
+ //
+ /// Presently only known in FLV.
+ typedef std::multimap<boost::uint64_t, boost::shared_ptr<SimpleBuffer> >
+ MetaTags;
+
+ typedef std::vector<MetaTags::mapped_type> OrderedMetaTags;
+ MediaParser(std::auto_ptr<IOChannel> stream);
// Classes with virtual methods (virtual classes)
// must have a virtual destructor, or the destructors
@@ -570,7 +573,16 @@
///
virtual bool parseNextChunk()=0;
- virtual void processTags(boost::uint64_t ts, as_object* thisPtr, VM&
env);
+ /// Retrieve any parsed metadata tags up to a specified timestamp.
+ //
+ /// @param ts The latest timestamp to retrieve metadata for.
+ /// @param tags This is filled with shared pointers to metatags in
+ /// timestamp order. Ownership of the data is shared. It
+ /// is destroyed automatically along with the last owner.
+ //
+ /// Metadata is currently only parsed from FLV streams. The default
+ /// is a no-op.
+ virtual void fetchMetaTags(OrderedMetaTags& tags, boost::uint64_t ts);
protected:
=== modified file 'libmedia/ffmpeg/MediaHandlerFfmpeg.cpp'
--- a/libmedia/ffmpeg/MediaHandlerFfmpeg.cpp 2008-10-28 19:29:24 +0000
+++ b/libmedia/ffmpeg/MediaHandlerFfmpeg.cpp 2009-01-03 09:54:35 +0000
@@ -37,23 +37,22 @@
{
std::auto_ptr<MediaParser> parser;
- if ( isFLV(*stream) )
- {
- parser.reset( new FLVParser(stream) );
- }
- else
- {
- try
- {
+ try {
+ if (isFLV(*stream))
+ {
+ parser.reset(new FLVParser(stream));
+ }
+ else
+ {
parser.reset(new MediaParserFfmpeg(stream));
}
- catch (GnashException& ex)
- {
- log_error("Could not create FFMPEG based media parser
for "
- "input stream: %s", ex.what());
- assert(!parser.get());
- }
- }
+ }
+ catch (GnashException& ex)
+ {
+ log_error("Could not create FFMPEG based media parser for "
+ "input stream: %s", ex.what());
+ assert(!parser.get());
+ }
return parser;
}
=== modified file 'libmedia/ffmpeg/MediaParserFfmpeg.cpp'
--- a/libmedia/ffmpeg/MediaParserFfmpeg.cpp 2008-12-19 20:17:52 +0000
+++ b/libmedia/ffmpeg/MediaParserFfmpeg.cpp 2009-01-03 09:54:35 +0000
@@ -69,8 +69,9 @@
if (actuallyRead < 1)
{
- throw IOException(_("MediaParserFfmpeg could not read probe
data from input"));
- return NULL;
+ throw IOException(_("MediaParserFfmpeg could not read probe
data "
+ "from input"));
+ return 0;
}
probe_data.buf_size = actuallyRead; // right ?
@@ -324,7 +325,8 @@
_inputFmt = probeStream();
if ( ! _inputFmt )
{
- throw GnashException("MediaParserFfmpeg couldn't figure out
input format");
+ throw MediaException("MediaParserFfmpeg couldn't figure out
input "
+ "format");
}
_formatCtx = av_alloc_format_context();
=== modified file 'libmedia/gst/MediaHandlerGst.cpp'
--- a/libmedia/gst/MediaHandlerGst.cpp 2008-11-26 08:25:29 +0000
+++ b/libmedia/gst/MediaHandlerGst.cpp 2009-01-03 09:54:35 +0000
@@ -43,23 +43,23 @@
{
std::auto_ptr<MediaParser> parser;
- if ( isFLV(*stream) )
- {
- parser.reset( new FLVParser(stream) );
- }
- else
- {
- try
- {
+ try
+ {
+ if (isFLV(*stream))
+ {
+ parser.reset(new FLVParser(stream));
+ }
+ else
+ {
parser.reset(new MediaParserGst(stream));
}
- catch (GnashException& ex)
- {
- log_error("Could not create Gstreamer based media
parser for "
- "input stream: %s", ex.what());
- assert(!parser.get());
- }
- }
+ }
+ catch (GnashException& ex)
+ {
+ log_error("Could not create Gstreamer based media parser for "
+ "input stream: %s", ex.what());
+ assert(!parser.get());
+ }
return parser;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10503: Remove libmedia dependency on libcore. Fix metadata handling crash,
Benjamin Wolsey <=