svvitch
digital signage player
D:/vs_workspace/switch_sf/src/svvitch/FlashContent.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines