svvitch
digital signage player
|
00001 #include "FlashContent.h" 00002 #include <Poco/UnicodeConverter.h> 00003 #include "Utils.h" 00004 00005 00006 FlashContent::FlashContent(Renderer& renderer, int splitType, float x, float y, float w, float h): ComContent(renderer, splitType, x, y, w, h), 00007 _module(NULL), _classFactory(NULL), _flash(NULL), _view(NULL), _zoom(0) 00008 { 00009 initialize(); 00010 } 00011 00012 FlashContent::‾FlashContent() { 00013 close(); 00014 SAFE_RELEASE(_classFactory); 00015 if (_module) { 00016 FreeLibrary(_module); 00017 _module = NULL; 00018 } 00019 } 00020 00021 void FlashContent::initialize() { 00022 char buf[MAX_PATH + 1]; 00023 GetSystemDirectoryA(buf, MAX_PATH + 1); 00024 string dir(buf); 00025 dir.append("¥¥macromed¥¥Flash¥¥"); 00026 00027 vector<string> files; 00028 files.push_back("flash11e.ocx"); // 11.1 00029 files.push_back("flash11c.ocx"); // 11.0 00030 files.push_back("flash10n.ocx"); // 10.2 00031 files.push_back("flash10l.ocx"); 00032 files.push_back("flash10k.ocx"); 00033 files.push_back("flash10j.ocx"); 00034 files.push_back("flash10i.ocx"); 00035 files.push_back("flash9.ocx"); 00036 for (int i = 0; i < files.size(); i++) { 00037 string lib(dir + files[i]); 00038 Poco::File f(lib); 00039 if (f.exists()) { 00040 _module = LoadLibraryA(lib.c_str()); 00041 if (_module) { 00042 DllGetClassObjectFunc aDllGetClassObjectFunc = (DllGetClassObjectFunc) GetProcAddress(_module, "DllGetClassObject"); 00043 aDllGetClassObjectFunc(CLSID_ShockwaveFlash, IID_IClassFactory, (void**)&_classFactory); 00044 if (!_classFactory) { 00045 FreeLibrary(_module); 00046 _module = NULL; 00047 } else { 00048 _log.information(Poco::format("load library: %s", lib)); 00049 break; 00050 } 00051 } 00052 } 00053 } 00054 00055 if (!_module) { 00056 _log.warning("failed not loading flash ActiveX"); 00057 return; 00058 } 00059 _phase = 0; 00060 } 00061 00062 void FlashContent::createComComponents() { 00063 HRESULT hr; 00064 if (_module) { 00065 if (_classFactory) { 00066 hr = _classFactory->CreateInstance(NULL, IID_IOleObject, (void**)&_ole); 00067 SAFE_RELEASE(_classFactory); 00068 if FAILED(hr) { 00069 _log.warning("failed create IOleObject"); 00070 _phase = -1; 00071 return; 00072 } 00073 _log.information("created class ShockwaveFlash(LoadLibrary)"); 00074 } else { 00075 _log.warning("failed create IOleObject"); 00076 _phase = -1; 00077 return; 00078 } 00079 } else { 00080 hr = CoCreateInstance(CLSID_ShockwaveFlash, NULL, CLSCTX_INPROC_SERVER, IID_IOleObject, (void**)&_ole); 00081 if FAILED(hr) { 00082 _log.warning("failed create IOleObject"); 00083 _phase = -1; 00084 return; 00085 } 00086 _log.information("created class ShockwaveFlash"); 00087 } 00088 00089 IOleClientSite* clientSite = NULL; 00090 hr = _controlSite->QueryInterface(__uuidof(IOleClientSite), (void**)&clientSite); 00091 if FAILED(hr) { 00092 _log.warning("failed not query IOleClientSite"); 00093 _phase = -1; 00094 return; 00095 } 00096 hr = _ole->SetClientSite(clientSite); 00097 if FAILED(hr) { 00098 _log.warning("failed not query IOleObject"); 00099 clientSite->Release(); 00100 _phase = -1; 00101 return; 00102 } 00103 00104 // Set the to transparent window mode 00105 hr = _ole->QueryInterface(__uuidof(IShockwaveFlash), (LPVOID*)&_flash); 00106 if FAILED(hr) { 00107 _log.warning("failed IShockwaveFlash"); 00108 clientSite->Release(); 00109 _phase = -1; 00110 return; 00111 } 00112 _flash->put_WMode(L"transparent"); // opaque 00113 00114 // In-place activate the object 00115 hr = _ole->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, clientSite, 0, NULL, NULL); 00116 clientSite->Release(); 00117 00118 hr = _flash->QueryInterface(IID_IViewObject, (LPVOID*)&_view); 00119 if FAILED(hr) { 00120 _log.warning("failed not query IViewObject"); 00121 _phase = -1; 00122 return; 00123 } 00124 IOleInPlaceObject* inPlaceObject = NULL; 00125 hr = _ole->QueryInterface(__uuidof(IOleInPlaceObject), (LPVOID*) &inPlaceObject); 00126 if FAILED(hr) { 00127 _log.warning("failed not query IOleInPlaceObject"); 00128 _phase = -1; 00129 return; 00130 } else { 00131 RECT rect; 00132 SetRect(&rect, 0, 0, _w, _h); 00133 inPlaceObject->SetObjectRects(&rect, &rect); 00134 inPlaceObject->Release(); 00135 } 00136 00137 if (!_params.empty()) { 00138 string params; 00139 svvitch::utf8_sjis(_params, params); 00140 _bstr_t bstr((char*)params.c_str()); 00141 HRESULT hr = _flash->put_FlashVars(bstr); 00142 if SUCCEEDED(hr) { 00143 _log.information(Poco::format("flashvars: %s", _params)); 00144 } else { 00145 _log.warning(Poco::format("failed flashvars: %s", _params)); 00146 } 00147 } 00148 _flash->put_Loop(VARIANT_FALSE); 00149 00150 string movie; 00151 svvitch::utf8_sjis(_movie, movie); 00152 hr = _flash->put_Movie(_bstr_t(movie.c_str())); 00153 if SUCCEEDED(hr) { 00154 _log.information(Poco::format("load movie: %s", _movie)); 00155 int retry = 10; 00156 while (_flash->ReadyState < 3 && retry-- > 0) { 00157 // 0=Loading・読み込み中 00158 // 1=Unintialized・初期化されていない 00159 // 2=Loaded・読み込み完了 00160 // 3=iNteractive・相互操作可能 00161 // 4=Complete・完了 00162 Poco::Thread::sleep(10); 00163 } 00164 _log.information(Poco::format("flash ready state: %ld", _flash->ReadyState)); 00165 if (_flash->ReadyState < 3) { 00166 _phase = -1; 00167 return; 00168 } 00169 00170 // flash->PutQuality2("low"); 00171 // flash->PutQuality2("medium"); 00172 // flash->PutQuality2("high"); 00173 // flash->PutQuality2("best"); 00174 // flash->PutQuality2("autolow"); 00175 // flash->PutQuality2("autohigh"); 00176 // flash->put_Quality2(L"medium"); 00177 if (!_quality.empty()) { 00178 string quality; 00179 svvitch::utf8_sjis(_quality, quality); 00180 _flash->put_Quality2(_bstr_t(quality.c_str())); 00181 } 00182 //flash->put_BackgroundColor(_background); 00183 //_flash->put_Scale(L"exactfit"); 00184 //_flash->put_Scale(L"showAll"); 00185 if (!_scale.empty()) { 00186 string scale; 00187 svvitch::utf8_sjis(_scale, scale); 00188 _flash->put_Scale(_bstr_t(scale.c_str())); 00189 } 00190 _flash->Zoom(_zoom); 00191 } else { 00192 _log.warning(Poco::format("failed movie: %s", _movie)); 00193 _phase = -1; 00194 return; 00195 } 00196 00197 _log.information("flash initialized"); 00198 _readCount = 0; 00199 _avgTime = 0; 00200 _phase = 1; 00201 } 00202 00203 void FlashContent::releaseComComponents() { 00204 Poco::ScopedLock<Poco::FastMutex> lock(_lock); 00205 SAFE_RELEASE(_view); 00206 SAFE_RELEASE(_flash); 00207 SAFE_RELEASE(_ole); 00208 _phase = 3; 00209 //_log.information("flash released"); 00210 } 00211 00213 bool FlashContent::open(const MediaItemPtr media, const int offset) { 00214 if (!_module) return false; 00215 00216 if (media->files().empty() || media->files().size() <= offset) return false; 00217 MediaItemFile mif = media->files()[offset]; 00218 string movie; 00219 if (mif.file().find("http://") == 0 || mif.file().find("https://") == 0) { 00220 movie = mif.file(); 00221 } else { 00222 movie = Path(mif.file()).absolute(config().dataRoot).toString(); 00223 Poco::File f(movie); 00224 if (!f.exists()) { 00225 _log.warning(Poco::format("file not found: %s", movie)); 00226 return false; 00227 } 00228 } 00229 _movie = movie; 00230 _params = mif.params(); 00231 _quality = media->getProperty("swf_quality", ""); 00232 _scale = media->getProperty("swf_scale", ""); 00233 _zoom = media->getNumProperty("swf_zoom", 0); 00234 _log.information(Poco::format("flash zoom: %d", _zoom)); 00235 _background = media->getHexProperty("swf_background", 0); 00236 _log.information(Poco::format("flash background: %lx", _background)); 00237 00238 return ComContent::open(media, offset); 00239 } 00240 00241 void FlashContent::run() { 00242 _log.information("start flash drawing thread"); 00243 00244 HDC hdc = NULL; 00245 PerformanceTimer timer; 00246 while (_playing && _surface && _view) { 00247 if (hasInvalidateRect()) { 00248 Rect rect = popInvalidateRect(); 00249 timer.start(); 00250 HRESULT hr = _surface->GetDC(&hdc); 00251 if SUCCEEDED(hr) { 00252 // SetMapMode(hdc, MM_TEXT); 00253 RECTL rectl = {rect.x, rect.y, rect.w, rect.h}; 00254 hr = _view->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, NULL, &rectl, NULL, 0); 00255 if FAILED(hr) { 00256 _log.warning("failed drawing flash"); 00257 break; 00258 } 00259 _surface->ReleaseDC(hdc); 00260 _readTime = timer.getTime(); 00261 _readCount++; 00262 if (_readCount > 0) _avgTime = F(_avgTime * (_readCount - 1) + _readTime) / _readCount; 00263 } else { 00264 _log.warning("failed getDC"); 00265 } 00266 Poco::Thread::sleep(0); 00267 } else { 00268 Poco::Thread::sleep(10); 00269 } 00270 } 00271 _log.information("finished flash drawing thread"); 00272 }