Projects
Essentials
lightspark
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 72
View file
lightspark.spec
Changed
@@ -24,7 +24,7 @@ %endif Name: lightspark -Version: 0.7.2.99+git20150614.1817 +Version: 0.7.2.99+git20150629.1759 Release: 0 Summary: Modern, free, open-source flash player implementation License: LGPL-3.0+
View file
lightspark.tar.xz/src/CMakeLists.txt
Changed
@@ -94,6 +94,7 @@ scripting/flash/net/URLRequestHeader.cpp scripting/flash/net/URLStream.cpp scripting/flash/net/XMLSocket.cpp + scripting/flash/net/NetStreamInfo.cpp scripting/flash/net/NetStreamPlayOptions.cpp scripting/flash/net/NetStreamPlayTransitions.cpp scripting/flash/printing/flashprinting.cpp
View file
lightspark.tar.xz/src/allclasses.cpp
Changed
@@ -51,6 +51,7 @@ #include "scripting/flash/net/URLRequestHeader.h" #include "scripting/flash/net/URLStream.h" #include "scripting/flash/net/XMLSocket.h" +#include "scripting/flash/net/NetStreamInfo.h" #include "scripting/flash/net/NetStreamPlayOptions.h" #include "scripting/flash/net/NetStreamPlayTransitions.h" #include "scripting/flash/printing/flashprinting.h"
View file
lightspark.tar.xz/src/allclasses.h
Changed
@@ -190,6 +190,7 @@ REGISTER_CLASS_NAME(NetGroup,"flash.net") REGISTER_CLASS_NAME(NetStream,"flash.net") REGISTER_CLASS_NAME(NetStreamAppendBytesAction,"flash.net") +REGISTER_CLASS_NAME(NetStreamInfo,"flash.net") REGISTER_CLASS_NAME(NetStreamPlayTransitions,"flash.net") REGISTER_CLASS_NAME(NetStreamPlayOptions,"flash.net") REGISTER_CLASS_NAME(ObjectEncoding,"flash.net")
View file
lightspark.tar.xz/src/asobject.cpp
Changed
@@ -93,7 +93,7 @@ } } -void ASObject::dumpVariables() +void ASObject::dumpVariables() const { LOG(LOG_INFO,"variables:"); Variables.dumpVariables(); @@ -1313,10 +1313,10 @@ #endif } -void variables_map::dumpVariables() +void variables_map::dumpVariables() const { - var_iterator it=Variables.begin(); - for(;it!=Variables.end();++it) + const_var_iterator it=Variables.cbegin(); + for(;it!=Variables.cend();++it) { const char* kind; switch(it->second.kind)
View file
lightspark.tar.xz/src/asobject.h
Changed
@@ -72,6 +72,18 @@ return ArgumentConversion<decltype(th->name)>::toAbstract(th->name); \ } +#define ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(c,name) \ + ASObject* c::_getter_##name(ASObject* obj, ASObject* const* args, const unsigned int argslen) \ + { \ + if(!obj->is<c>()) \ + throw Class<ArgumentError>::getInstanceS("Function applied to wrong object"); \ + c* th = obj->as<c>(); \ + if(argslen != 0) \ + throw Class<ArgumentError>::getInstanceS("Arguments provided in getter"); \ + LOG(LOG_NOT_IMPLEMENTED,obj->getClassName() <<"."<< #name << " is not implemented"); \ + return ArgumentConversion<decltype(th->name)>::toAbstract(th->name); \ + } + /* full body for a getter declared by ASPROPERTY_SETTER or ASFUNCTION_SETTER */ #define ASFUNCTIONBODY_SETTER(c,name) \ ASObject* c::_setter_##name(ASObject* obj, ASObject* const* args, const unsigned int argslen) \ @@ -257,7 +269,7 @@ void serialize(ByteArray* out, std::map<tiny_string, uint32_t>& stringMap, std::map<const ASObject*, uint32_t>& objMap, std::map<const Class_base*, uint32_t>& traitsMap) const; - void dumpVariables(); + void dumpVariables() const; void destroyContents(); }; @@ -496,7 +508,7 @@ /* applies proxy namespace settings to name for internal usage */ void applyProxyProperty(multiname &name); - void dumpVariables(); + void dumpVariables() const; void setConstructIndicator() { constructIndicator = true; }
View file
lightspark.tar.xz/src/backends/decoder.cpp
Changed
@@ -805,7 +805,7 @@ stream.read((char*)probeData.buf,8192); int read=stream.gcount(); if(read!=8192) - LOG(LOG_ERROR,_("Not sufficient data is available from the stream")); + LOG(LOG_ERROR,"Not sufficient data is available from the stream:"<<read); probeData.buf_size=read; stream.seekg(0); @@ -911,7 +911,10 @@ else { if (customVideoDecoder) + { customVideoDecoder->decodePacket(&pkt, mtime); + customVideoDecoder->framesdecoded++; + } } av_free_packet(&pkt); return true;
View file
lightspark.tar.xz/src/backends/decoder.h
Changed
@@ -85,7 +85,7 @@ class VideoDecoder: public Decoder, public ITextureUploadable { public: - VideoDecoder():frameRate(0),frameWidth(0),frameHeight(0),fenceCount(0),resizeGLBuffers(false){} + VideoDecoder():frameRate(0),framesdecoded(0),frameWidth(0),frameHeight(0),fenceCount(0),resizeGLBuffers(false){} virtual ~VideoDecoder(){}; virtual bool decodeData(uint8_t* data, uint32_t datalen, uint32_t time)=0; virtual bool discardFrame()=0; @@ -100,6 +100,7 @@ return frameHeight; } double frameRate; + uint32_t framesdecoded; /* Useful to avoid destruction of the object while a pending upload is waiting */
View file
lightspark.tar.xz/src/backends/netutils.cpp
Changed
@@ -172,7 +172,13 @@ LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager::download '") << url.getParsedURL() << "'" << (cached ? _(" - cached") : "")); ThreadedDownloader* downloader; - if(url.getProtocol() == "file") + // empty URL means data is generated from calls to NetStream::appendBytes + if(url.isEmpty()) + { + LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: Data generation mode")); + downloader=new LocalDownloader(url.getPath(), cache, owner,true); + } + else if(url.getProtocol() == "file") { LOG(LOG_INFO, _("NET: STANDALONE: DownloadManager: local file")); downloader=new LocalDownloader(url.getPath(), cache, owner); @@ -701,8 +707,8 @@ * \param[in] _url The URL for the Downloader. * \param[in] _cached Whether or not to cache this download. */ -LocalDownloader::LocalDownloader(const tiny_string& _url, _R<StreamCache> _cache, ILoadable* o): - ThreadedDownloader(_url, _cache, o) +LocalDownloader::LocalDownloader(const tiny_string& _url, _R<StreamCache> _cache, ILoadable* o, bool dataGeneration): + ThreadedDownloader(_url, _cache, o),dataGenerationMode(dataGeneration) { } @@ -724,7 +730,7 @@ */ void LocalDownloader::execute() { - if(url.empty()) + if(url.empty() && !dataGenerationMode) { setFailed(); return; @@ -788,7 +794,8 @@ } } //Notify the downloader no more data should be expected - setFinished(); + if(!dataGenerationMode) + setFinished(); } DownloaderThreadBase::DownloaderThreadBase(_NR<URLRequest> request, IDownloaderThreadListener* _listener): listener(_listener), downloader(NULL)
View file
lightspark.tar.xz/src/backends/netutils.h
Changed
@@ -202,6 +202,7 @@ class LocalDownloader: public ThreadedDownloader { private: + bool dataGenerationMode; static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp); static size_t write_header(void *buffer, size_t size, size_t nmemb, void *userp); static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); @@ -211,7 +212,7 @@ //Size of the reading buffer static const size_t bufSize = 8192; public: - LocalDownloader(const tiny_string& _url, _R<StreamCache> _cache, ILoadable* o); + LocalDownloader(const tiny_string& _url, _R<StreamCache> _cache, ILoadable* o, bool dataGeneration = false); }; class IDownloaderThreadListener
View file
lightspark.tar.xz/src/backends/security.cpp
Changed
@@ -575,6 +575,10 @@ SecurityManager::EVALUATIONRESULT SecurityManager::evaluatePoliciesURL(const URLInfo& url, bool loadPendingPolicies) { + //This check doesn't apply to data generation mode + if(url.isEmpty()) + return ALLOWED; + //This check doesn't apply to local files if(url.getProtocol() == "file" && getSys()->mainClip->getOrigin().getProtocol() == "file") return ALLOWED; @@ -583,6 +587,8 @@ //http://forums.adobe.com/thread/422391) if(url.isRTMP()) return ALLOWED; + if(url.isValid()) + return ALLOWED; LOG(LOG_INFO, _("SECURITY: Evaluating URL for cross domain policies:")); LOG(LOG_INFO, _("SECURITY: --> URL: ") << url); @@ -671,6 +677,9 @@ SecurityManager::EVALUATIONRESULT SecurityManager::evaluateHeader(const URLInfo& url, const tiny_string& header, bool loadPendingPolicies) { + //This check doesn't apply to data generation mode + if (url.isEmpty()) + return ALLOWED; //This check doesn't apply to local files if(url.getProtocol() == "file" && getSys()->mainClip->getOrigin().getProtocol() == "file") return ALLOWED;
View file
lightspark.tar.xz/src/backends/streamcache.cpp
Changed
@@ -437,22 +437,31 @@ markFinished(); } -void FileStreamCache::waitForCache() +void FileStreamCache::openForWriting() { if (cache.is_open()) return; + openCache(); +} + +bool FileStreamCache::waitForCache() +{ + if (cache.is_open()) + return true; // Cache file will be opened when the first byte is received waitForData(0); - // Check if the stream was terminated before anything was written - if (!cache.is_open()) - throw RunTimeException(_("FileStreamCache::waitForCache: cache file is not open")); + return cache.is_open(); } std::streambuf *FileStreamCache::createReader() { - waitForCache(); + if (!waitForCache()) + { + LOG(LOG_ERROR,"could not open cache file"); + return NULL; + } incRef(); FileStreamCache::Reader *fbuf = new FileStreamCache::Reader(_MR(this)); @@ -460,7 +469,7 @@ if (!fbuf->is_open()) { delete fbuf; - throw RunTimeException(_("FileStreamCache::createReader: opening cache file for reading failed")); + return NULL; } return fbuf; }
View file
lightspark.tar.xz/src/backends/streamcache.h
Changed
@@ -178,7 +178,7 @@ void openExistingCache(const tiny_string& filename, bool forWriting=true) DLL_LOCAL; // Block until the cache file is opened by the writer stream - void waitForCache() DLL_LOCAL; + bool waitForCache() DLL_LOCAL; virtual void handleAppend(const unsigned char* buffer, size_t length) DLL_LOCAL; @@ -190,8 +190,9 @@ // Use an existing file as cache. Must be called before append(). void useExistingFile(const tiny_string& filename); + void openForWriting(); }; -}; +} #endif // BACKENDS_STREAMCACHE_H
View file
lightspark.tar.xz/src/backends/urlutils.h
Changed
@@ -70,6 +70,7 @@ URLInfo(const tiny_string& u); ~URLInfo() {}; bool isValid() const { return valid; } + bool isEmpty() const { return !valid && invalidReason == IS_EMPTY; } INVALID_REASON getInvalidReason() const { return invalidReason; }; //Remove extraneous slashes, .. and . from URLs
View file
lightspark.tar.xz/src/plugin/plugin.cpp
Changed
@@ -66,6 +66,11 @@ */ lightspark::Downloader* NPDownloadManager::download(const lightspark::URLInfo& url, _R<StreamCache> cache, lightspark::ILoadable* owner) { + // empty URL means data is generated from calls to NetStream::appendBytes + if(!url.isValid() && url.getInvalidReason() == URLInfo::IS_EMPTY) + { + return StandaloneDownloadManager::download(url, cache, owner); + } // Handle RTMP requests internally, not through NPAPI if(url.isRTMP()) { @@ -210,7 +215,10 @@ e=NPN_PostURLNotify(th->instance, th->url.raw_buf(), NULL, tmpData.size(), (const char*)&tmpData[0], false, th); } if(e!=NPERR_NO_ERROR) + { + LOG(LOG_ERROR,"download failed for " << th->url << " code:"<<e); th->setFailed(); //No need to crash, we can just mark the download failed + } } char* NPP_GetMIMEDescription(void) @@ -361,7 +369,7 @@ //basedir is a qualified URL or a path relative to the HTML page URLInfo page(getPageURL()); m_sys->mainClip->setBaseURL(page.goToURL(baseURL).getURL()); - + m_sys->downloadManager=new NPDownloadManager(mInstance); } else
View file
lightspark.tar.xz/src/scripting/abc.cpp
Changed
@@ -94,6 +94,7 @@ #include "scripting/flash/net/URLRequestHeader.h" #include "scripting/flash/net/URLStream.h" #include "scripting/flash/net/XMLSocket.h" +#include "scripting/flash/net/NetStreamInfo.h" #include "scripting/flash/net/NetStreamPlayOptions.h" #include "scripting/flash/net/NetStreamPlayTransitions.h" #include "scripting/flash/printing/flashprinting.h" @@ -441,6 +442,7 @@ builtin->registerBuiltin("NetGroup","flash.net",Class<NetGroup>::getRef()); builtin->registerBuiltin("NetStream","flash.net",Class<NetStream>::getRef()); builtin->registerBuiltin("NetStreamAppendBytesAction","flash.net",Class<NetStreamAppendBytesAction>::getRef()); + builtin->registerBuiltin("NetStreamInfo","flash.net",Class<NetStreamInfo>::getRef()); builtin->registerBuiltin("NetStreamPlayOptions","flash.net",Class<NetStreamPlayOptions>::getRef()); builtin->registerBuiltin("NetStreamPlayTransitions","flash.net",Class<NetStreamPlayTransitions>::getRef()); builtin->registerBuiltin("URLLoader","flash.net",Class<URLLoader>::getRef()); @@ -2152,7 +2154,7 @@ #ifdef PROFILING_SUPPORT if(!m->validProfName) { - m->profName=prot->class_name.name+"::"+mname->qualifiedString(); + m->profName=obj->getClassName()+"::"+mname->qualifiedString(); m->validProfName=true; } #endif
View file
lightspark.tar.xz/src/scripting/flash/display/BitmapData.cpp
Changed
@@ -84,6 +84,7 @@ c->setDeclaredMethodByQName("colorTransform","",Class<IFunction>::getFunction(colorTransform),NORMAL_METHOD,true); c->setDeclaredMethodByQName("compare","",Class<IFunction>::getFunction(compare),NORMAL_METHOD,true); c->setDeclaredMethodByQName("applyFilter","",Class<IFunction>::getFunction(applyFilter),NORMAL_METHOD,true); + c->setDeclaredMethodByQName("noise","",Class<IFunction>::getFunction(noise),NORMAL_METHOD,true); // properties c->setDeclaredMethodByQName("height","",Class<IFunction>::getFunction(_getHeight),GETTER_METHOD,true); @@ -851,3 +852,15 @@ LOG(LOG_NOT_IMPLEMENTED,"BitmapData.applyFilter not implemented"); return NULL; } +ASFUNCTIONBODY(BitmapData,noise) +{ + BitmapData* th = obj->as<BitmapData>(); + int randomSeed; + uint low; + uint high; + uint channelOptions; + bool grayScale; + ARG_UNPACK(randomSeed)(low, 0) (high, 255) (channelOptions, 7) (grayScale, false); + LOG(LOG_NOT_IMPLEMENTED,"BitmapData.noise not implemented"); + return NULL; +}
View file
lightspark.tar.xz/src/scripting/flash/display/BitmapData.h
Changed
@@ -84,6 +84,7 @@ ASFUNCTION(colorTransform); ASFUNCTION(compare); ASFUNCTION(applyFilter); + ASFUNCTION(noise); }; };
View file
lightspark.tar.xz/src/scripting/flash/display/DisplayObject.cpp
Changed
@@ -620,9 +620,10 @@ DisplayObject* th=static_cast<DisplayObject*>(obj); assert_and_throw(argslen==1); - if(args[0]->is<Undefined>()) + if(args[0]->is<Undefined>() || args[0]->is<Null>()) return Class<Rectangle>::getInstanceS(); - + if (!args[0]->is<DisplayObject>()) + LOG(LOG_ERROR,"DisplayObject.getBounds invalid type:"<<args[0]->toDebugString()); assert_and_throw(args[0]->is<DisplayObject>()); DisplayObject* target=Class<DisplayObject>::cast(args[0]); //Compute the transformation matrix @@ -861,10 +862,7 @@ _NR<RootMovieClip> DisplayObject::getRoot() { if(parent.isNull()) - { - LOG(LOG_ERROR,"DisplayObject has no root:"<<this->toDebugString()); return NullRef; - } return parent->getRoot(); }
View file
lightspark.tar.xz/src/scripting/flash/net/NetStreamInfo.cpp
Added
@@ -0,0 +1,106 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#include "scripting/flash/net/NetStreamInfo.h" +#include "scripting/class.h" +#include "scripting/argconv.h" + +using namespace std; +using namespace lightspark; + +NetStreamInfo::NetStreamInfo(Class_base* c):ASObject(c) + ,audioBufferByteLength(-1) + ,audioBufferLength(-1) + ,audioByteCount(-1) + ,audioBytesPerSecond(-1) + ,audioLossRate(-1) + ,byteCount(-1) + ,currentBytesPerSecond(-1) + ,dataBufferByteLength(-1) + ,dataBufferLength(-1) + ,dataByteCount(-1) + ,dataBytesPerSecond(-1) + ,droppedFrames(0) + ,isLive(false) + ,maxBytesPerSecond(-1) + ,metaData(NULL) + ,playbackBytesPerSecond(-1) + ,SRTT(-1) + ,videoBufferByteLength(-1) + ,videoBufferLength(-1) + ,videoByteCount(-1) + ,videoBytesPerSecond(-1) + ,videoLossRate(-1) + ,xmpData(NULL) +{ +} +void NetStreamInfo::sinit(Class_base* c) +{ + CLASS_SETUP_NO_CONSTRUCTOR(c, ASObject, CLASS_FINAL|CLASS_SEALED); + REGISTER_GETTER(c,audioBufferByteLength); + REGISTER_GETTER(c,audioBufferLength); + REGISTER_GETTER(c,audioByteCount); + REGISTER_GETTER(c,audioBytesPerSecond); + REGISTER_GETTER(c,audioLossRate); + REGISTER_GETTER(c,byteCount); + REGISTER_GETTER(c,currentBytesPerSecond); + REGISTER_GETTER(c,dataBufferByteLength); + REGISTER_GETTER(c,dataBufferLength); + REGISTER_GETTER(c,dataByteCount); + REGISTER_GETTER(c,dataBytesPerSecond); + REGISTER_GETTER(c,droppedFrames); + REGISTER_GETTER(c,isLive); + REGISTER_GETTER(c,maxBytesPerSecond); + REGISTER_GETTER(c,metaData); + REGISTER_GETTER(c,playbackBytesPerSecond); + REGISTER_GETTER(c,resourceName); + REGISTER_GETTER(c,SRTT); + REGISTER_GETTER(c,uri); + REGISTER_GETTER(c,videoBufferByteLength); + REGISTER_GETTER(c,videoBufferLength); + REGISTER_GETTER(c,videoByteCount); + REGISTER_GETTER(c,videoBytesPerSecond); + REGISTER_GETTER(c,videoLossRate); + REGISTER_GETTER(c,xmpData); +} + +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,audioBufferByteLength); +ASFUNCTIONBODY_GETTER(NetStreamInfo,audioBufferLength); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,audioByteCount); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,audioBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,audioLossRate); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,byteCount); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,currentBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,dataBufferByteLength); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,dataBufferLength); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,dataByteCount); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,dataBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,droppedFrames); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,isLive); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,maxBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,metaData); +ASFUNCTIONBODY_GETTER(NetStreamInfo,playbackBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,resourceName); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,SRTT); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,uri); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,videoBufferByteLength); +ASFUNCTIONBODY_GETTER(NetStreamInfo,videoBufferLength); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,videoByteCount); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,videoBytesPerSecond); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,videoLossRate); +ASFUNCTIONBODY_GETTER_NOT_IMPLEMENTED(NetStreamInfo,xmpData); +
View file
lightspark.tar.xz/src/scripting/flash/net/NetStreamInfo.h
Added
@@ -0,0 +1,59 @@ +/************************************************************************** + Lightspark, a free flash player implementation + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +**************************************************************************/ + +#ifndef NETSTREAMINFO_H +#define NETSTREAMINFO_H + +#include "asobject.h" + +namespace lightspark +{ + +class NetStreamInfo: public ASObject +{ +public: + NetStreamInfo(Class_base* c); + static void sinit(Class_base*); + ASPROPERTY_GETTER(number_t,audioBufferByteLength); + ASPROPERTY_GETTER(number_t,audioBufferLength); + ASPROPERTY_GETTER(number_t,audioByteCount); + ASPROPERTY_GETTER(number_t,audioBytesPerSecond); + ASPROPERTY_GETTER(number_t,audioLossRate); + ASPROPERTY_GETTER(number_t,byteCount); + ASPROPERTY_GETTER(number_t,currentBytesPerSecond); + ASPROPERTY_GETTER(number_t,dataBufferByteLength); + ASPROPERTY_GETTER(number_t,dataBufferLength); + ASPROPERTY_GETTER(number_t,dataByteCount); + ASPROPERTY_GETTER(number_t,dataBytesPerSecond); + ASPROPERTY_GETTER(number_t,droppedFrames); + ASPROPERTY_GETTER(bool,isLive); + ASPROPERTY_GETTER(number_t,maxBytesPerSecond); + ASPROPERTY_GETTER(_NR<ASObject>,metaData); + ASPROPERTY_GETTER(number_t,playbackBytesPerSecond); + ASPROPERTY_GETTER(tiny_string,resourceName); + ASPROPERTY_GETTER(number_t,SRTT); + ASPROPERTY_GETTER(tiny_string,uri); + ASPROPERTY_GETTER(number_t,videoBufferByteLength); + ASPROPERTY_GETTER(number_t,videoBufferLength); + ASPROPERTY_GETTER(number_t,videoByteCount); + ASPROPERTY_GETTER(number_t,videoBytesPerSecond); + ASPROPERTY_GETTER(number_t,videoLossRate); + ASPROPERTY_GETTER(_NR<ASObject>,xmpData); +}; + +} +#endif // NETSTREAMInfo_H
View file
lightspark.tar.xz/src/scripting/flash/net/URLStream.cpp
Changed
@@ -33,9 +33,19 @@ using namespace lightspark; URLStreamThread::URLStreamThread(_R<URLRequest> request, _R<URLStream> ldr, _R<ByteArray> bytes) - : DownloaderThreadBase(request, ldr.getPtr()), loader(ldr), data(bytes) + : DownloaderThreadBase(request, ldr.getPtr()), loader(ldr), data(bytes),streambuffer(NULL) { } +void URLStreamThread::setBytesLoaded(uint32_t b) +{ + uint32_t curlen = data->getLength(); + if(b>curlen && streambuffer) + { + data->append(streambuffer,b - curlen); + loader->incRef(); + getVm()->addEvent(loader,_MR(Class<ProgressEvent>::getInstanceS(b,0))); + } +} void URLStreamThread::execute() { @@ -44,16 +54,19 @@ //TODO: support httpStatus, progress events _R<MemoryStreamCache> cache(_MR(new MemoryStreamCache)); - if(!createDownloader(cache, loader)) + if(!createDownloader(cache, loader,this)) return; bool success=false; if(!downloader->hasFailed()) { + loader->incRef(); getVm()->addEvent(loader,_MR(Class<Event>::getInstanceS("open"))); + streambuffer = cache->createReader(); cache->waitForTermination(); if(!downloader->hasFailed() && !threadAborting) { + /* std::streambuf *sbuf = cache->createReader(); istream s(sbuf); uint8_t* buf=new uint8_t[downloader->getLength()]; @@ -62,8 +75,9 @@ //TODO: test binary data format data->acquireBuffer(buf,downloader->getLength()); //The buffers must not be deleted, it's now handled by the ByteArray instance - success=true; delete sbuf; + */ + success=true; } } @@ -71,11 +85,13 @@ if(success && !threadAborting) { //Send a complete event for this object + loader->incRef(); getVm()->addEvent(loader,_MR(Class<Event>::getInstanceS("complete"))); } else if(!success && !threadAborting) { //Notify an error during loading + loader->incRef(); getVm()->addEvent(loader,_MR(Class<IOErrorEvent>::getInstanceS())); } @@ -112,11 +128,14 @@ c->setDeclaredMethodByQName("readUnsignedShort","",Class<IFunction>::getFunction(readUnsignedShort),NORMAL_METHOD,true); c->setDeclaredMethodByQName("readUTF","",Class<IFunction>::getFunction(readUTF),NORMAL_METHOD,true); c->setDeclaredMethodByQName("readUTFBytes","",Class<IFunction>::getFunction(readUTFBytes),NORMAL_METHOD,true); + REGISTER_GETTER(c,connected); c->addImplementedInterface(InterfaceClass<IDataInput>::getClass()); IDataInput::linkTraits(c); } +ASFUNCTIONBODY_GETTER(URLStream,connected); + void URLStream::buildTraits(ASObject* o) { } @@ -170,6 +189,7 @@ URLStreamThread *job=new URLStreamThread(urlRequest, _MR(th), th->data); getSys()->addJob(job); th->job=job; + th->connected = true; return NULL; } @@ -179,6 +199,7 @@ SpinlockLocker l(th->spinlock); if(th->job) th->job->threadAbort(); + th->connected = false; return NULL; }
View file
lightspark.tar.xz/src/scripting/flash/net/URLStream.h
Changed
@@ -32,14 +32,17 @@ class URLStream; -class URLStreamThread : public DownloaderThreadBase +class URLStreamThread : public DownloaderThreadBase, public ILoadable { private: _R<URLStream> loader; _R<ByteArray> data; + std::streambuf *streambuffer; void execute(); public: URLStreamThread(_R<URLRequest> request, _R<URLStream> ldr, _R<ByteArray> bytes); + void setBytesTotal(uint32_t b) { (void)b; } + void setBytesLoaded(uint32_t b); }; class URLStream: public EventDispatcher, public IDataInput, public IDownloaderThreadListener @@ -72,8 +75,9 @@ ASFUNCTION(readUnsignedShort); ASFUNCTION(readUTF); ASFUNCTION(readUTFBytes); + ASPROPERTY_GETTER(bool,connected); public: - URLStream(Class_base* c):EventDispatcher(c),data(_MNR(Class<ByteArray>::getInstanceS())),job(NULL) {} + URLStream(Class_base* c):EventDispatcher(c),data(_MNR(Class<ByteArray>::getInstanceS())),job(NULL),connected(false) {} static void sinit(Class_base*); static void buildTraits(ASObject* o); void threadFinished(IThreadJob *job);
View file
lightspark.tar.xz/src/scripting/flash/net/flashnet.cpp
Changed
@@ -1029,8 +1029,8 @@ NetStream::NetStream(Class_base* c):EventDispatcher(c),tickStarted(false),paused(false),closed(true), streamTime(0),frameRate(0),connection(),downloader(NULL),videoDecoder(NULL), - audioDecoder(NULL),audioStream(NULL), - client(NullRef),oldVolume(-1.0),checkPolicyFile(false),rawAccessAllowed(false), + audioDecoder(NULL),audioStream(NULL),datagenerationfile(NULL),datagenerationthreadstarted(false),framesdecoded(0), + client(NullRef),oldVolume(-1.0),checkPolicyFile(false),rawAccessAllowed(false),playbackBytesPerSecond(0), backBufferLength(0),backBufferTime(30),bufferLength(0),bufferTime(0.1),bufferTimeMax(0), maxPauseBufferTime(0) { @@ -1050,6 +1050,8 @@ getSys()->removeJob(this); delete videoDecoder; delete audioDecoder; + if (datagenerationfile) + delete datagenerationfile; } void NetStream::sinit(Class_base* c) @@ -1081,6 +1083,7 @@ REGISTER_GETTER_SETTER(c, bufferTimeMax); REGISTER_GETTER_SETTER(c, maxPauseBufferTime); REGISTER_GETTER_SETTER(c,soundTransform); + c->setDeclaredMethodByQName("info","",Class<IFunction>::getFunction(_getInfo),GETTER_METHOD,true); } void NetStream::buildTraits(ASObject* o) @@ -1095,6 +1098,16 @@ ASFUNCTIONBODY_GETTER_SETTER(NetStream, maxPauseBufferTime); ASFUNCTIONBODY_GETTER_SETTER(NetStream,soundTransform); +ASFUNCTIONBODY(NetStream,_getInfo) +{ + NetStream* th=Class<NetStream>::cast(obj); + NetStreamInfo* res = Class<NetStreamInfo>::getInstanceS(); + res->playbackBytesPerSecond = th->playbackBytesPerSecond; + res->audioBufferLength = th->bufferLength; + res->videoBufferLength = th->bufferLength; + return res; +} + ASFUNCTIONBODY(NetStream,_getClient) { NetStream* th=Class<NetStream>::cast(obj); @@ -1173,6 +1186,14 @@ th->paused = false; // th->audioPaused = false; + // Parameter Null means data is generated by calls to "appendBytes" + if (args[0]->is<Null>()) + { + th->datagenerationfile = new FileStreamCache; + th->datagenerationfile->openForWriting(); + th->streamTime=0; + return NULL; + } if (th->connection.isNull()) throwError<ASError>(0,"not connected"); @@ -1331,14 +1352,38 @@ ARG_UNPACK(bytearray); if(!bytearray.isNull()) - th->downloader->append(bytearray->getBuffer(bytearray->getLength(),false),bytearray->getLength()); + { + if (th->datagenerationfile) + { + th->datagenerationfile->append(bytearray->getBuffer(bytearray->getLength(),false),bytearray->getLength()); + if (!th->datagenerationthreadstarted && th->datagenerationfile->getReceivedLength() >= 8192) + { + th->datagenerationthreadstarted = true; + th->incRef(); + getSys()->addJob(th); + } + } + + } return NULL; } ASFUNCTIONBODY(NetStream,appendBytesAction) { - //NetStream* th=Class<NetStream>::cast(obj); - LOG(LOG_NOT_IMPLEMENTED,"NetStream.appendBytesAction is not implemented yet"); - assert_and_throw(argslen == 1); + NetStream* th=Class<NetStream>::cast(obj); + tiny_string val; + ARG_UNPACK(val); + + if (val == "resetBegin") + { + LOG(LOG_INFO,"NetStream.appendBytesAction:"<<val<<" "<<th->url); + if (th->datagenerationfile) + delete th->datagenerationfile; + th->datagenerationfile = new FileStreamCache; + th->datagenerationfile->openForWriting(); + } + + else + LOG(LOG_NOT_IMPLEMENTED,"NetStream.appendBytesAction is not implemented yet:"<<val); return NULL; } @@ -1358,7 +1403,7 @@ if(paused) return; //Advance video and audio to current time, follow the audio stream time - //No mutex needed, ticking can happen only when stream is completely ready + countermutex.lock(); if(audioStream && getSys()->audioManager->isTimingAvailablePlugin()) { assert(audioDecoder); @@ -1370,6 +1415,9 @@ if (audioDecoder) audioDecoder->skipAll(); } + this->bufferLength = (framesdecoded / frameRate) - (streamTime-prevstreamtime)/1000.0; + //LOG(LOG_INFO,"tick:"<< " "<<bufferLength << " "<<streamTime<<" "<<frameRate<<" "<<framesdecoded<<" "<<bufferTime<<" "<<this->playbackBytesPerSecond<<" "<<this->getReceivedLength()); + countermutex.unlock(); videoDecoder->skipUntil(streamTime); //The next line ensures that the downloader will not be destroyed before the upload jobs are fenced videoDecoder->waitForFencing(); @@ -1411,17 +1459,29 @@ if(evaluationResult == SecurityManager::NA_CROSSDOMAIN_POLICY) rawAccessAllowed = true; - if(downloader->hasFailed()) + std::streambuf *sbuf = NULL; + if (datagenerationfile) { - this->incRef(); - getVm()->addEvent(_MR(this),_MR(Class<IOErrorEvent>::getInstanceS())); - getSys()->downloadManager->destroy(downloader); - return; + LOG(LOG_INFO,"create reader"); + sbuf = datagenerationfile->createReader(); + } + else + { + if (!downloader) + return; + if(downloader->hasFailed()) + { + this->incRef(); + getVm()->addEvent(_MR(this),_MR(Class<IOErrorEvent>::getInstanceS())); + getSys()->downloadManager->destroy(downloader); + downloader = NULL; + return; + } + + //The downloader hasn't failed yet at this point + + sbuf = downloader->getCache()->createReader(); } - - //The downloader hasn't failed yet at this point - - std::streambuf *sbuf = downloader->getCache()->createReader(); istream s(sbuf); s.exceptions(istream::goodbit); @@ -1434,10 +1494,22 @@ { #ifdef ENABLE_LIBAVCODEC Chronometer chronometer; - streamDecoder=new FFMpegStreamDecoder(s); - if(!streamDecoder->isValid()) + if (!sbuf) + { threadAbort(); + } + else + { + streamDecoder=new FFMpegStreamDecoder(s); + if(!streamDecoder->isValid()) + threadAbort(); + } + + countermutex.lock(); + this->prevstreamtime = streamTime; + this->bufferLength = 0; + countermutex.unlock(); bool done=false; while(!done) { @@ -1450,6 +1522,29 @@ bool decodingSuccess=streamDecoder->decodeNextFrame(); if(decodingSuccess==false) done = true; + else + { + if (streamDecoder->videoDecoder) + { + if (streamDecoder->videoDecoder->framesdecoded != framesdecoded) + { + countermutex.lock(); + + framesdecoded = streamDecoder->videoDecoder->framesdecoded; + if(frameRate==0) + { + assert(streamDecoder->videoDecoder->frameRate); + frameRate=streamDecoder->videoDecoder->frameRate; + } + if (frameRate) + { + this->bufferLength = (framesdecoded / frameRate) - (streamTime-prevstreamtime)/1000.0; + this->playbackBytesPerSecond = s.tellg() / (framesdecoded / frameRate); + } + countermutex.unlock(); + } + } + } if(videoDecoder==NULL && streamDecoder->videoDecoder) { @@ -1457,27 +1552,22 @@ this->incRef(); getVm()->addEvent(_MR(this), _MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Play.Start"))); - this->incRef(); - getVm()->addEvent(_MR(this), - _MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Buffer.Full"))); } - if(audioDecoder==NULL && streamDecoder->audioDecoder) - audioDecoder=streamDecoder->audioDecoder; - - if(audioStream==NULL && audioDecoder && audioDecoder->isValid() && getSys()->audioManager->pluginLoaded()) - audioStream=getSys()->audioManager->createStreamPlugin(audioDecoder); - - if(!tickStarted && isReady()) + if(!tickStarted && isReady() && ((framesdecoded / frameRate) >= this->bufferTime)) { + if(audioDecoder==NULL && streamDecoder->audioDecoder) + audioDecoder=streamDecoder->audioDecoder; + + if(audioStream==NULL && audioDecoder && audioDecoder->isValid() && getSys()->audioManager->pluginLoaded()) + audioStream=getSys()->audioManager->createStreamPlugin(audioDecoder); + sendClientNotification("onMetaData", createMetaDataObject(streamDecoder)); tickStarted=true; - if(frameRate==0) - { - assert(videoDecoder->frameRate); - frameRate=videoDecoder->frameRate; - } + this->incRef(); + getVm()->addEvent(_MR(this), + _MR(Class<NetStatusEvent>::getInstanceS("status", "NetStream.Buffer.Full"))); getSys()->addTick(1000/frameRate,this); //Also ask for a render rate equal to the video one (capped at 24) float localRenderRate=dmin(frameRate,24); @@ -1533,7 +1623,8 @@ videoDecoder=NULL; audioDecoder=NULL; //Clean up everything for a possible re-run - getSys()->downloadManager->destroy(downloader); + if (downloader) + getSys()->downloadManager->destroy(downloader); //This transition is critical, so the mutex is needed downloader=NULL; delete audioStream; @@ -1702,12 +1793,16 @@ uint32_t NetStream::getReceivedLength() { assert(isReady()); + if (datagenerationfile) + return datagenerationfile->getReceivedLength(); return downloader->getReceivedLength(); } uint32_t NetStream::getTotalLength() { assert(isReady()); + if (datagenerationfile) + return 0; return downloader->getLength(); }
View file
lightspark.tar.xz/src/scripting/flash/net/flashnet.h
Changed
@@ -28,6 +28,7 @@ #include "timer.h" #include "backends/decoder.h" #include "backends/interfaces/audio/IAudioPlugin.h" +#include "NetStreamInfo.h" namespace lightspark { @@ -248,7 +249,11 @@ VideoDecoder* videoDecoder; AudioDecoder* audioDecoder; AudioStream *audioStream; + // only used when in DataGenerationMode + FileStreamCache* datagenerationfile; + bool datagenerationthreadstarted; Mutex mutex; + Mutex countermutex; //IThreadJob interface for long jobs void execute(); void threadAbort(); @@ -268,6 +273,11 @@ bool checkPolicyFile; bool rawAccessAllowed; + uint32_t framesdecoded; + uint32_t prevstreamtime; + number_t playbackBytesPerSecond; + + ASObject *createMetaDataObject(StreamDecoder* streamDecoder); ASObject *createPlayStatusObject(const tiny_string& code); void sendClientNotification(const tiny_string& name, ASObject *args); @@ -295,6 +305,7 @@ ASFUNCTION(attach); ASFUNCTION(appendBytes); ASFUNCTION(appendBytesAction); + ASFUNCTION(_getInfo); ASPROPERTY_GETTER(number_t, backBufferLength); ASPROPERTY_GETTER_SETTER(number_t, backBufferTime); ASPROPERTY_GETTER(number_t, bufferLength);
View file
lightspark.tar.xz/src/scripting/flash/utils/ByteArray.cpp
Changed
@@ -527,7 +527,13 @@ //Return the length of the serialized object //TODO: support AMF0 - assert_and_throw(objectEncoding==ObjectEncoding::AMF3); + + if (objectEncoding==ObjectEncoding::AMF0) + { + LOG(LOG_NOT_IMPLEMENTED,"ByteArray.writeObject: writing AMF0 objects not implemented"); + //return 0; + } + //assert_and_throw(objectEncoding==ObjectEncoding::AMF3); //TODO: support custom serialization map<tiny_string, uint32_t> stringMap; map<const ASObject*, uint32_t> objMap; @@ -1001,9 +1007,8 @@ _NR<ASObject> ByteArray::getVariableByMultiname(const multiname& name, GET_VARIABLE_OPTION opt) { - assert_and_throw(implEnable); unsigned int index=0; - if((opt & ASObject::SKIP_IMPL)!=0 || !Array::isValidMultiname(name,index)) + if((opt & ASObject::SKIP_IMPL)!=0 || !implEnable || !Array::isValidMultiname(name,index)) return ASObject::getVariableByMultiname(name,opt); if(index<len) @@ -1155,6 +1160,16 @@ position+=xmlstr.numBytes(); } } +void ByteArray::append(streambuf *data, int length) +{ + lock(); + int oldlen = len; + getBuffer(len+length,true); + istream s(data); + s.read((char*)bytes+oldlen,length); + unlock(); +} + void ByteArray::compress_zlib() {
View file
lightspark.tar.xz/src/scripting/flash/utils/ByteArray.h
Changed
@@ -68,6 +68,8 @@ uint32_t getPosition() const; void setPosition(uint32_t p); + void append(std::streambuf* data, int length); + uint8_t getCurrentObjectEncoding() const { return currentObjectEncoding; } void setCurrentObjectEncoding(uint8_t encoding) { currentObjectEncoding = encoding; }
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.cpp
Changed
@@ -1211,7 +1211,7 @@ xmlpp::Element* factory=root->add_child("factory"); factory->set_attribute("type", getQualifiedClassName().raw_buf()); describeInstance(factory); - + return Class<XML>::getInstanceS(root); } @@ -1242,6 +1242,14 @@ // variables, methods, accessors c=this; + if (c->class_index<0) + { + // builtin class + LOG(LOG_NOT_IMPLEMENTED, "describeType for builtin classes not completely implemented:"<<this->class_name); + std::map<tiny_string, xmlpp::Element*> instanceNodes; + describeVariables(root,c,instanceNodes,Variables); + describeVariables(root,c,instanceNodes,borrowedVariables); + } while(c && c->class_index>=0) { c->describeTraits(root, c->context->instances[c->class_index].traits); @@ -1249,6 +1257,48 @@ } } +void Class_base::describeVariables(xmlpp::Element* root,const Class_base* c, std::map<tiny_string, xmlpp::Element*>& instanceNodes, const variables_map& map) const +{ + variables_map::const_var_iterator it=map.Variables.cbegin(); + for(;it!=map.Variables.cend();++it) + { + const char* nodename; + const char* access = NULL; + switch (it->second.kind) + { + case CONSTANT_TRAIT: + nodename = "constant"; + break; + case DECLARED_TRAIT: + case INSTANCE_TRAIT: + if (it->second.var) + nodename="method"; + else + { + nodename="accessor"; + if (it->second.getter && it->second.setter) + access = "readwrite"; + else if (it->second.getter) + access = "readonly"; + else if (it->second.setter) + access = "writeonly"; + } + break; + default: + continue; + } + tiny_string name = getSys()->getStringFromUniqueId(it->first.nameId); + auto existing=instanceNodes.find(name); + if(existing != instanceNodes.cend()) + continue; + + xmlpp::Element* node=root->add_child(nodename); + instanceNodes[name] = node; + node->set_attribute("name", name.raw_buf()); + if (access) + node->set_attribute("access", access); + } +} void Class_base::describeTraits(xmlpp::Element* root, std::vector<traits_info>& traits) const {
View file
lightspark.tar.xz/src/scripting/toplevel/toplevel.h
Changed
@@ -152,6 +152,7 @@ IFunction* constructor; void describeTraits(xmlpp::Element* root, std::vector<traits_info>& traits) const; void describeMetadata(xmlpp::Element* node, const traits_info& trait) const; + void describeVariables(xmlpp::Element *root,const Class_base* c, std::map<tiny_string, xmlpp::Element*>& instanceNodes, const variables_map& map) const; //Naive garbage collection until reference cycles are detected Mutex referencedObjectsMutex; boost::intrusive::list<ASObject, boost::intrusive::constant_time_size<false> > referencedObjects;
View file
lightspark.tar.xz/src/swf.cpp
Changed
@@ -236,6 +236,7 @@ threadPool=new ThreadPool(this); timerThread=new TimerThread(this); + frameTimerThread=new TimerThread(this); pluginManager = new PluginManager; audioManager=new AudioManager(pluginManager); intervalManager=new IntervalManager(); @@ -376,6 +377,7 @@ getline(i,value); ret->setVariableByQName(name,"",Class<ASString>::getInstanceS(value),DYNAMIC_TRAIT); + //cout << name << ' ' << value << endl; } setParameters(ret); i.close(); @@ -421,6 +423,7 @@ if(threadPool) threadPool->forceStop(); timerThread->wait(); + frameTimerThread->wait(); /* first shutdown the vm, because it can use all the others */ if(currentVm) currentVm->shutdown(); @@ -441,7 +444,7 @@ #ifdef PROFILING_SUPPORT void SystemState::saveProfilingInformation() { - if(profOut.len()) + if(profOut.numBytes()) { ofstream f(profOut.raw_buf()); f << "events: Time" << endl; @@ -617,7 +620,9 @@ //Some objects needs to remove the jobs when destroyed so keep the timerThread until now delete timerThread; timerThread=NULL; - + delete frameTimerThread; + frameTimerThread= NULL; + delete renderThread; renderThread=NULL; delete inputThread; @@ -654,6 +659,7 @@ error=true; errorCause=c; timerThread->stop(); + frameTimerThread->stop(); //Disable timed rendering removeJob(renderThread); renderThread->draw(true); @@ -998,6 +1004,11 @@ timerThread->addTick(tickTime,job); } +void SystemState::addFrameTick(uint32_t tickTime, ITickJob* job) +{ + frameTimerThread->addTick(tickTime,job); +} + void SystemState::addWait(uint32_t waitTime, ITickJob* job) { timerThread->addWait(waitTime,job); @@ -1584,7 +1595,7 @@ if(this==sys->mainClip) { /* now the frameRate is available and all SymbolClass tags have created their classes */ - sys->addTick(1000/frameRate,sys); + sys->addFrameTick(1000/frameRate,sys); } else {
View file
lightspark.tar.xz/src/swf.h
Changed
@@ -161,6 +161,7 @@ friend class SystemState::EngineCreator; ThreadPool* threadPool; TimerThread* timerThread; + TimerThread* frameTimerThread; Semaphore terminated; float renderRate; bool error; @@ -348,6 +349,7 @@ //Interfaces to the internal thread pool and timer thread void addJob(IThreadJob* j) DLL_PUBLIC; void addTick(uint32_t tickTime, ITickJob* job); + void addFrameTick(uint32_t tickTime, ITickJob* job); void addWait(uint32_t waitTime, ITickJob* job); void removeJob(ITickJob* job);
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.