StString StProcess::getStCoreFolder() { StString aCoreEnvValue = getEnv(ST_ENV_NAME_STCORE_PATH); #ifdef _WIN32 if(aCoreEnvValue.isEmpty()) { // read env. value directly from registry (before first log off / log in) const StString aRegisterPath = "Environment"; loadStringFromRegister(aRegisterPath, ST_ENV_NAME_STCORE_PATH, aCoreEnvValue); } #endif // repair filesystem splitter if(!aCoreEnvValue.isEmpty() && !aCoreEnvValue.isEndsWith(SYS_FS_SPLITTER)) { aCoreEnvValue += StString(SYS_FS_SPLITTER); } if(isValidStCorePath(aCoreEnvValue)) { // environment variable is correctly set return aCoreEnvValue; } const StString aProcessPath = getProcessFolder(); if(isValidStCorePath(aProcessPath)) { return aProcessPath; } return StString(); }
int StActiveXCtrl::OnCreate(LPCREATESTRUCT theCreateStruct) { myBackBrush.CreateSolidBrush(RGB(0, 0, 0)); if(COleControl::OnCreate(theCreateStruct) == -1) { return -1; } const StString ST_ASTERIX = '*'; StMIME aMime(StString(myMimeType), ST_ASTERIX, ST_ASTERIX); myOpenInfo.setMIME(aMime); StArgumentsMap aDrawerArgs; const StString ST_SETTING_SRCFORMAT = stCString("srcFormat"); const StString ST_SETTING_COMPRESS = stCString("toCompress"); const StString ST_SETTING_ESCAPENOQUIT = stCString("escNoQuit"); const StMIME ST_MIME_X_JPS("image/x-jps", ST_ASTERIX, ST_ASTERIX); const StMIME ST_MIME_JPS ("image/jps", ST_ASTERIX, ST_ASTERIX); const StMIME ST_MIME_X_PNS("image/x-pns", ST_ASTERIX, ST_ASTERIX); const StMIME ST_MIME_PNS ("image/pns", ST_ASTERIX, ST_ASTERIX); StArgument anArgSrcFormat = aDrawerArgs[ST_SETTING_SRCFORMAT]; if(!anArgSrcFormat.isValid()) { anArgSrcFormat.setKey(ST_SETTING_SRCFORMAT); if(aMime == ST_MIME_X_JPS || aMime == ST_MIME_JPS || aMime == ST_MIME_X_PNS || aMime == ST_MIME_PNS) { anArgSrcFormat.setValue(st::formatToString(StFormat_SideBySide_RL)); aDrawerArgs.add(anArgSrcFormat); } } aDrawerArgs.add(StArgument(ST_SETTING_COMPRESS, "true")); // optimize memory usage aDrawerArgs.add(StArgument(ST_SETTING_ESCAPENOQUIT, "true")); // do not close plugin instance by Escape key myOpenInfo.setArgumentsMap(aDrawerArgs); // set window myParentWin = m_hWnd; // starts out plugin main loop in another thread myThread = new StThread(stThreadFunction, (void* )this, "StActiveXCtrl"); // load URL StString aFilePath = loadURL(myHasPreview ? myUrlPreview : myUrlFull); if(aFilePath.isEmpty()) { if(!myHasPreview) { return 0; } if(myHasPreview) { // if we have 2 URLs - try to load another one aFilePath = loadURL(myUrlFull); if(aFilePath.isEmpty()) { return 0; } myHasPreview = false; } } myOpenInfo.setPath(aFilePath); myOpenEvent.set(); return 0; }
unsigned int decodeHotKey(const StString& theString) { unsigned int aKey = 0; if(theString.isEmpty()) { return aKey; } // decode flags (split by + separator) StUtf8Iter aFrom = theString.iterator(); StUtf8Iter anIter = theString.iterator(); for(; *anIter != 0; ++anIter) { if(*anIter == stUtf32_t('+')) { if(anIter.getIndex() == 0) { return ST_VK_OEM_PLUS; // single '+' } const StCStringUtf8 aSubStr = { aFrom.getBufferHere(), size_t(anIter.getBufferHere() - aFrom.getBufferHere()), anIter.getIndex() - aFrom.getIndex() }; if(aSubStr.isEquals(THE_VKEYS_NAMES[ST_VK_SHIFT])) { aKey |= ST_VF_SHIFT; } else if(aSubStr.isEquals(THE_VKEYS_NAMES[ST_VK_CONTROL])) { aKey |= ST_VF_CONTROL; } aFrom = anIter; ++aFrom; } } // decode VKey itself const StCStringUtf8 aSubStr = { aFrom.getBufferHere(), size_t(anIter.getBufferHere() - aFrom.getBufferHere()), anIter.getIndex() - aFrom.getIndex() }; if(aSubStr.Size == 1) { // optimized code for letters if(*aSubStr.String >= 'A' && *aSubStr.String <= 'Z') { aKey |= (unsigned int )*aSubStr.String; return aKey; } else if(*aSubStr.String >= '0' && *aSubStr.String <= '9') { aKey |= (unsigned int )*aSubStr.String; return aKey; } } for(unsigned int aKeyIter = 0; aKeyIter <= 223; ++aKeyIter) { if(aSubStr.isEquals(THE_VKEYS_NAMES[aKeyIter])) { aKey |= aKeyIter; break; } } return aKey; }
int main(int , char** ) { // force console output #else int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { // prevent console output #endif setlocale(LC_ALL, ".OCP"); // we set default locale for console output (useful only for debug) #else int main(int , char** ) { #endif StOutPageFlip::initGlobalsAsync(); if(!StVersionInfo::checkTimeBomb("sView")) { return 1; } // setup environment variables const StString ST_ENV_NAME_STCORE_PATH = #if defined(_WIN64) || defined(_LP64) || defined(__LP64__) "StCore64"; #else "StCore32"; #endif const StString aProcessPath = StProcess::getProcessFolder(); StString aProcessUpPath = StFileNode::getFolderUp(aProcessPath); if(!aProcessUpPath.isEmpty()) { aProcessUpPath += SYS_FS_SPLITTER; } StProcess::setEnv(ST_ENV_NAME_STCORE_PATH, aProcessPath); if(StFolder::isFolder(aProcessPath + "textures")) { StProcess::setEnv("StShare", aProcessPath); } else if(StFolder::isFolder(aProcessUpPath + "textures")) { StProcess::setEnv("StShare", aProcessUpPath); } StString aResDir = StProcess::getStShareFolder(); StProcess::setEnv("CSF_UnitsLexicon", aResDir + "UnitsAPI" ST_FILE_SPLITTER "Lexi_Expr.dat"); StProcess::setEnv("CSF_UnitsDefinition", aResDir + "UnitsAPI" ST_FILE_SPLITTER "Units.dat"); StProcess::setEnv("CSF_ShadersDirectory", aResDir + "shaders" ST_FILE_SPLITTER "StCADViewer"); StProcess::setEnv("CSF_SHMessage", aResDir + "lang"); StProcess::setEnv("CSF_MDTVTexturesDirectory", aResDir + "textures"); StHandle<StOpenInfo> anInfo; if(anInfo.isNull() || (!anInfo->hasPath() && !anInfo->hasArgs())) { anInfo = StApplication::parseProcessArguments(); } if(anInfo.isNull()) { // show help StString aShowHelpString = getAbout(); st::cout << aShowHelpString; stInfo(aShowHelpString); return 0; } StHandle<StResourceManager> aResMgr = new StResourceManager(); StHandle<StCADViewer> anApp = new StCADViewer(aResMgr, NULL, anInfo); if(!anApp->open()) { return 1; } return anApp->exec(); }
LRESULT StActiveXCtrl::WindowProc(UINT theMsg, WPARAM theParamW, LPARAM theParamL) { // Special case for WM_INITMENUPOPUP event. // Standard implementation of COleControl::WindowProc does not find handlers for popup menu items created // by plugin and disables them if(theMsg == WM_INITMENUPOPUP) { return 0; } else if(theMsg == WM_ERASEBKGND) { return 1; } else if(theMsg == WM_PAINT) { if(!myIsActive) { PAINTSTRUCT aPaintStruct; CDC* aDevCtx = BeginPaint(&aPaintStruct); FillRect(aDevCtx->GetSafeHdc(), &aPaintStruct.rcPaint, myBackBrush); EndPaint(&aPaintStruct); } return 0; } // use fake WM_TIMER event to switch between fullscreen / windowed image in correct thread if(theMsg == WM_TIMER && myHasPreview) { if(theParamW == 1) { const StString aFilePath = loadURL(myUrlFull); if(!aFilePath.isEmpty()) { myOpenInfo.setPath(aFilePath); myOpenEvent.set(); } else { // don't try to load broken URL anymore myHasPreview = false; } } else if(theParamW == 0) { const StString aFilePath = loadURL(myUrlPreview); if(!aFilePath.isEmpty()) { myOpenInfo.setPath(aFilePath); myOpenEvent.set(); } else { // don't try to load broken URL anymore myHasPreview = false; } } } return COleControl::WindowProc(theMsg, theParamW, theParamL); }
size_t StPlayList::findRecent(const StString thePathL, const StString thePathR) const { StFileNode aNode; if(thePathR.isEmpty()) { aNode.setSubPath(thePathL); } else { aNode.add(new StFileNode(thePathL, &aNode)); aNode.add(new StFileNode(thePathR, &aNode)); } StMutexAuto anAutoLock(myMutex); for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { const StHandle<StRecentItem>& aRecent = myRecent[anIter]; if(stAreSameRecent(aNode, *aRecent->File)) { return anIter; } } return size_t(-1); }
bool StGLProgram::link(StGLContext& theCtx) { if(!isValid()) { return false; } theCtx.core20fwd->glLinkProgram(myProgramId); // if linkage failed - automatically remove the program! if(!isLinked(theCtx)) { theCtx.pushError(StString("Linking of the program '") + myTitle + "' failed!\n" + getLinkageInfo(theCtx)); release(theCtx); return false; } #ifdef __ST_DEBUG_SHADERS__ const StString anInfo = getLinkageInfo(theCtx); ST_DEBUG_LOG("Program '" + myTitle + "' has been linked" + (!anInfo.isEmpty() ? (StString(". Log:\n") + anInfo) : (StString()))); #endif return true; }
void StPlayList::open(const StCString& thePath, const StCString& theItem) { StMutexAuto anAutoLock(myMutex); // check if it is recently played playlist bool hasTarget = !theItem.isEmpty(); StString aTarget = hasTarget ? theItem : thePath; if(!hasTarget) { for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { const StHandle<StRecentItem>& aRecent = myRecent[anIter]; const StHandle<StFileNode>& aFile = aRecent->File; if(aFile->size() != 1) { continue; } if(thePath.isEquals(aFile->getPath())) { hasTarget = true; aTarget = aFile->getValue(0)->getSubPath(); break; } } } clear(); int aSearchDeep = myRecursionDeep; StString aFolderPath; StString aFileName; if(StFolder::isFolder(thePath)) { // add all files from the folder and subfolders aFolderPath = thePath; aSearchDeep = myRecursionDeep; myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list } else if(StFileNode::isFileExists(thePath)) { // search only current folder StFileNode::getFolderAndFile(thePath, aFolderPath, aFileName); aSearchDeep = 1; bool hasSupportedExt = false; StString anExt = StFileNode::getExtension(aFileName); for(size_t anExtId = 0; anExtId < myExtensions.size() && !hasSupportedExt; ++anExtId) { hasSupportedExt = anExt.isEqualsIgnoreCase(myExtensions[anExtId]); } // parse m3u playlist if(anExt.isEqualsIgnoreCase(stCString("m3u"))) { StRawFile aRawFile(thePath); if(aRawFile.readFile()) { StString aTitle; char* anIter = (char* )aRawFile.getBuffer(); if(anIter[0] == '\xEF' && anIter[1] == '\xBB' && anIter[2] == '\xBF') { // skip BOM for UTF8 written by some stupid programs anIter += 3; } while(anIter != NULL) { anIter = parseM3UIter(anIter, aTitle); } myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list if(hasTarget) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); return; } } if(!hasSupportedExt) { // file with unsupported extension? StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addPlayItem(new StPlayItem(aFileNode, myDefStParams)); } } else { // not a filesystem element - probably url or invalid path StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addRecentFile(*aFileNode); // append to recent files list addPlayItem(new StPlayItem(aFileNode, myDefStParams)); anAutoLock.unlock(); signals.onPlaylistChange(); return; } StFolder* aSubFolder = new StFolder(aFolderPath, &myFoldersRoot); aSubFolder->init(myExtensions, aSearchDeep); myFoldersRoot.add(aSubFolder); addToPlayList(aSubFolder); myCurrent = myFirst; if(hasTarget || !aFileName.isEmpty()) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; if(myPlsFile.isNull()) { addRecentFile(*anItem->getFileNode()); // append to recent files list } break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); }
void StWindowImpl::processEvents() { if(myParentWin == NULL || myToResetDevice) { // window is closed! return; } // check if we are exiting if(myParentWin->ToDestroy()) { myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); return; } // check onNewIntent event StString aDndFile; myParentWin->setHardwareStereoOn(myToEnableStereoHW); myParentWin->setTrackOrientation(myToTrackOrient); myParentWin->setHideSystemBars(myToHideStatusBar, myToHideNavBar); myParentWin->fetchState(aDndFile, myQuaternion, myToSwapEyesHW, myKeysState); if(!aDndFile.isEmpty()) { std::vector<const char*> aDndList; aDndList.push_back(aDndFile.toCString()); myStEvent.Type = stEvent_FileDrop; myStEvent.DNDrop.Time = getEventTime(); myStEvent.DNDrop.NbFiles = aDndList.size(); myStEvent.DNDrop.Files = &aDndList[0]; myEventsBuffer.append(myStEvent); } updateActiveState(); StPointD_t anOldMousePt = myMousePt; int aPollRes = 0; int aNbEvents = 0; StAndroidPollSource* aSource = NULL; bool toWaitEvents = false; while((aPollRes = ALooper_pollAll(toWaitEvents ? -1 : 0, NULL, &aNbEvents, (void** )&aSource)) >= 0) { if(aSource != NULL) { aSource->process(myParentWin, aSource); } if(myToResetDevice) { break; } // check if we are exiting if(myParentWin->ToDestroy()) { break; } } // check if we are exiting if(myParentWin->ToDestroy()) { myStEvent.Type = stEvent_Close; myStEvent.Close.Time = getEventTime(); signals.onClose->emit(myStEvent.Close); return; } myIsMouseMoved = false; if(myMousePt.x() >= 0.0 && myMousePt.x() <= 1.0 && myMousePt.y() >= 0.0 && myMousePt.y() <= 1.0) { StPointD_t aDspl = myMousePt - anOldMousePt; if(std::abs(aDspl.x()) >= 0.0008 || std::abs(aDspl.y()) >= 0.0008) { myIsMouseMoved = true; } } // update position only when all messages are parsed updateWindowPos(); myIsUpdated = false; // StWindow XLib implementation process events in the same thread // thus this double buffer is not in use // however user events may be posted to it swapEventsBuffers(); }
void StLogger::write(const StString& theMessage, const StLogger::Level theLevel, const StLogContext* ) { if(theLevel > myFilter || theMessage.isEmpty()) { // just ignore return; } // lock for safety if(!myMutex.isNull()) { myMutex->lock(); } // log to the file if(!myFilePath.isEmpty()) { #ifdef _WIN32 myFileHandle = _wfopen(myFilePath.toCString(), L"ab"); #elif defined(__linux__) myFileHandle = fopen(myFilePath.toCString(), "ab"); #endif if(myFileHandle != NULL) { switch(theLevel) { case ST_PANIC: fwrite("PANIC !! ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; case ST_FATAL: fwrite("FATAL !! ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; case ST_ERROR: fwrite("ERROR !! ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; case ST_WARNING: fwrite("WARN -- ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; case ST_INFO: case ST_VERBOSE: fwrite("INFO -- ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; case ST_DEBUG: fwrite("DEBUG -- ", 1, 9, myFileHandle); fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; default: fwrite(theMessage.toCString(), 1, theMessage.getSize(), myFileHandle); break; } fwrite("\n", 1, 1, myFileHandle); fclose(myFileHandle); myFileHandle = NULL; } } // log to standard output (with colored prefix) if(myToLogCout) { switch(theLevel) { case ST_PANIC: ST_LOG_CERR << st::COLOR_FOR_RED << stostream_text("PANIC !! ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; case ST_FATAL: ST_LOG_CERR << st::COLOR_FOR_RED << stostream_text("FATAL !! ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; case ST_ERROR: ST_LOG_CERR << st::COLOR_FOR_RED << stostream_text("ERROR !! ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; case ST_WARNING: ST_LOG_CERR << st::COLOR_FOR_YELLOW_L << stostream_text("WARN -- ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; case ST_INFO: case ST_VERBOSE: ST_LOG_CERR << st::COLOR_FOR_YELLOW_L << stostream_text("INFO -- ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; case ST_DEBUG: ST_LOG_CERR << st::COLOR_FOR_YELLOW_L << stostream_text("DEBUG -- ") << st::COLOR_FOR_WHITE << theMessage << stostream_text('\n'); break; default: ST_LOG_CERR << theMessage << stostream_text('\n'); break; } } // log to the system journal(s) /*#ifdef _WIN32 // get a handle to the event log HANDLE anEventLog = RegisterEventSource(NULL, // local computer L"sView"); // event source name if(anEventLog != NULL) { WORD aLogType = 0; switch(theLevel) { case ST_PANIC: case ST_FATAL: case ST_ERROR: aLogType = EVENTLOG_ERROR_TYPE; break; case ST_WARNING: aLogType = EVENTLOG_WARNING_TYPE; break; case ST_INFO: case ST_VERBOSE: case ST_DEBUG: default: aLogType = EVENTLOG_INFORMATION_TYPE; break; } ReportEvent(anEventLog, aLogType, 0, // event category 0, // event identifier NULL, // no user security identifier 1, // number of substitution strings 0, // no data (LPCWSTR* )&theMessage.utfText(), // pointer to strings NULL)) // no binary data DeregisterEventSource(anEventLog); } #endif*/ // unlock mutex if(!myMutex.isNull()) { myMutex->unlock(); } }
bool StAVVideoMuxer::save(const StString& theFile) { if(myCtxListSrc.isEmpty() || theFile.isEmpty()) { return false; } StString aFormatName = myCtxListSrc[0]->iformat->name; const char* aFormatStr = formatToMetadata(myStereoFormat); std::vector<StRemuxContext> aSrcCtxList; //StArrayList<StRemuxContext> aSrcCtxList; unsigned int aStreamCount = 0; StAVOutContext aCtxOut; if(!aCtxOut.findFormat(NULL, theFile.toCString())) { signals.onError(StString("Unable to find a suitable output format for '") + theFile + "'."); return false; } else if(!aCtxOut.create(theFile)) { signals.onError(StString("Could not create output context.")); return false; } for(size_t aCtxId = 0; aCtxId < myCtxListSrc.size(); ++aCtxId) { StRemuxContext aCtxSrc; aCtxSrc.Context = myCtxListSrc[aCtxId]; if(aCtxId == 0) { av_dict_copy(&aCtxOut.Context->metadata, aCtxSrc.Context->metadata, AV_DICT_DONT_OVERWRITE); av_dict_set(&aCtxOut.Context->metadata, "STEREO_MODE", aFormatStr, 0); } for(unsigned int aStreamId = 0; aStreamId < aCtxSrc.Context->nb_streams; ++aStreamId) { aCtxSrc.Streams.add((unsigned int )-1); AVStream* aStreamSrc = aCtxSrc.Context->streams[aStreamId]; if(aStreamSrc->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if(addStream(aCtxOut.Context, aStreamSrc)) { aCtxSrc.Streams[aStreamId] = aStreamCount++; } } } aSrcCtxList.push_back(aCtxSrc); } // add audio streams after video for(size_t aCtxId = 0; aCtxId < myCtxListSrc.size(); ++aCtxId) { StRemuxContext& aCtxSrc = aSrcCtxList[aCtxId]; for(unsigned int aStreamId = 0; aStreamId < aCtxSrc.Context->nb_streams; ++aStreamId) { AVStream* aStreamSrc = aCtxSrc.Context->streams[aStreamId]; if(aStreamSrc->codec->codec_type == AVMEDIA_TYPE_AUDIO && addStream(aCtxOut.Context, aStreamSrc)) { aCtxSrc.Streams[aStreamId] = aStreamCount++; } } } // add other streams (subtitles) at the end for(size_t aCtxId = 0; aCtxId < myCtxListSrc.size(); ++aCtxId) { StRemuxContext& aCtxSrc = aSrcCtxList[aCtxId]; for(unsigned int aStreamId = 0; aStreamId < aCtxSrc.Context->nb_streams; ++aStreamId) { AVStream* aStreamSrc = aCtxSrc.Context->streams[aStreamId]; if(aStreamSrc->codec->codec_type != AVMEDIA_TYPE_VIDEO && aStreamSrc->codec->codec_type != AVMEDIA_TYPE_AUDIO && addStream(aCtxOut.Context, aStreamSrc)) { aCtxSrc.Streams[aStreamId] = aStreamCount++; } } } av_dump_format(aCtxOut.Context, 0, theFile.toCString(), 1); if(!(aCtxOut.Context->oformat->flags & AVFMT_NOFILE)) { const int aState = avio_open2(&aCtxOut.Context->pb, theFile.toCString(), AVIO_FLAG_WRITE, NULL, NULL); if(aState < 0) { signals.onError(StString("Could not open output file '") + theFile + "' (" + stAV::getAVErrorDescription(aState) + ")"); return false; } } int aState = avformat_write_header(aCtxOut.Context, NULL); if(aState < 0) { signals.onError(StString("Error occurred when opening output file (") + stAV::getAVErrorDescription(aState) + ")."); return false; } AVPacket aPacket; for(;;) { size_t aNbEmpty = 0; for(size_t aCtxId = 0; aCtxId < aSrcCtxList.size(); ++aCtxId) { StRemuxContext& aCtxSrc = aSrcCtxList[aCtxId]; if(!aCtxSrc.State) { ++aNbEmpty; continue; } if(av_read_frame(aCtxSrc.Context, &aPacket) < 0) { aCtxSrc.State = false; ++aNbEmpty; continue; } unsigned int aStreamOutIndex = aCtxSrc.Streams[aPacket.stream_index]; if(aStreamOutIndex == (unsigned int )-1) { continue; } AVStream* aStreamIn = aCtxSrc.Context->streams[aPacket.stream_index]; AVStream* aStreamOut = aCtxOut.Context->streams[aStreamOutIndex]; #ifdef ST_LIBAV_FORK const AVRounding aRoundParams = AV_ROUND_NEAR_INF; #else const AVRounding aRoundParams = AVRounding(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); #endif aPacket.pts = av_rescale_q_rnd(aPacket.pts, aStreamIn->time_base, aStreamOut->time_base, aRoundParams); aPacket.dts = av_rescale_q_rnd(aPacket.dts, aStreamIn->time_base, aStreamOut->time_base, aRoundParams); aPacket.duration = static_cast<int >(av_rescale_q(aPacket.duration, aStreamIn->time_base, aStreamOut->time_base)); aPacket.pos = -1; aState = av_interleaved_write_frame(aCtxOut.Context, &aPacket); if(aState < 0) { signals.onError(StString("Error muxing packet (") + stAV::getAVErrorDescription(aState) + ")."); return false; } av_free_packet(&aPacket); } if(aNbEmpty == aSrcCtxList.size()) { break; } } av_write_trailer(aCtxOut.Context); return true; }
void StTranslations::reload() { params.language->changeValues().clear(); // detect available translations StArrayList<StString> aFolders; myResMgr->listSubFolders("lang", aFolders); for(size_t aNodeId = 0; aNodeId < aFolders.size(); ++aNodeId) { myLangFolderList.add(aFolders[aNodeId]); const StString aNameFile = StString("lang" ST_FILE_SPLITTER) + aFolders[aNodeId] + ST_FILE_SPLITTER "language.lng"; StHandle<StResource> aRes = myResMgr->getResource(aNameFile); StString aName; if(!aRes.isNull() && aRes->read()) { const char* aSrc = (const char* )aRes->getData(); const size_t aLen = (size_t )aRes->getSize(); aName = StString(aSrc, aLen); } params.language->changeValues().add(aName.isEmpty() ? aFolders[aNodeId] : aName); } #if defined(__ANDROID__) if(params.language->getValues().isEmpty()) { // no way to list sub-folder on Android - check known translations if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "English" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("English"); myLangFolderList.add("English"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Russian" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("русский"); myLangFolderList.add("Russian"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "French" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("français"); myLangFolderList.add("French"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "German" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("Deutsch"); myLangFolderList.add("German"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Korean" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("한국어"); myLangFolderList.add("Korean"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "ChineseS" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("简体中文"); myLangFolderList.add("ChineseS"); } if(myResMgr->isResourceExist(StString("lang" ST_FILE_SPLITTER "Czech" ST_FILE_SPLITTER) + myModuleName + StTranslations::DEFAULT_SUFFIX)) { params.language->changeValues().add("Čeština"); myLangFolderList.add("Czech"); } } #endif if(params.language->getValues().isEmpty()) { // add built-in language params.language->changeValues().add("English"); myLangFolderList.add("English"); } size_t anIdInList = 0; StString aLangParam("English"); StSettings aGlobalSettings(myResMgr, ST_GLOBAL_SETTINGS_GROUP); bool isLangSet = false; if(!aGlobalSettings.loadString(ST_SETTING_LANGUAGE, aLangParam)) { // try to use system-wide language settings const StString& aLang = myResMgr->getSystemLanguage(); if(aLang.isEqualsIgnoreCase(stCString("ru"))) { if(myLangFolderList.contains(stCString("Russian"), anIdInList) || myLangFolderList.contains(stCString("русский"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } else if(aLang.isEqualsIgnoreCase(stCString("de"))) { if(myLangFolderList.contains(stCString("German"), anIdInList) || myLangFolderList.contains(stCString("Deutsch"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } else if(aLang.isEqualsIgnoreCase(stCString("fr"))) { if(myLangFolderList.contains(stCString("French"), anIdInList) || myLangFolderList.contains(stCString("français"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } else if(aLang.isEqualsIgnoreCase(stCString("ko"))) { if(myLangFolderList.contains(stCString("Korean"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } else if(aLang.isEqualsIgnoreCase(stCString("zh"))) { if(myLangFolderList.contains(stCString("ChineseS"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } else if(aLang.isEqualsIgnoreCase(stCString("cs"))) { if(myLangFolderList.contains(stCString("Čeština"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); isLangSet = true; } } } if(!isLangSet) { if(myLangFolderList.contains(aLangParam, anIdInList) || myLangFolderList.contains(stCString("English"), anIdInList)) { params.language->setValue(int32_t(anIdInList)); } } updateLangCode(int32_t(anIdInList)); const StString& aFolderName = myLangFolderList[anIdInList]; const StString aResName = StString() + "lang" + SYS_FS_SPLITTER + aFolderName + SYS_FS_SPLITTER + myModuleName + StTranslations::DEFAULT_SUFFIX; StHandle<StResource> aRes = myResMgr->getResource(aResName); if(!aRes.isNull() && aRes->read()) { const char* aSrc = (const char* )aRes->getData(); const int aLen = aRes->getSize(); read(aSrc, aLen); } // connect signal params.language->signals.onChanged.connect(this, &StTranslations::setLanguage); }